Dynamic icons & colours in Asynchronous webserver

What I will describe might be cut and dry for many people but beginners may struggle with it, hence this short instruction.

Asynchronous webservers have some distinct advantages, he main one being the possibility to automatically update necessary elements of the served website without having to refresh the entire website. A typical example is a website with server readings. Only updating the readings without updating the entire website makes for a quiter few that is much easier on the eye. Asynchronous websites are typically combined with Websockets, Single Server events and/or AJAX/JavaScript.

Websites with sensor readings are often glammed up with icons and colours and it would be nice to be able to change those as well, depending on the server readings. An example is a thermometer icon showing a high scale in red when it is warm and a low scale in blue when it is cold.

In order not to reinvent the wheel, I will take an example from the randomnerdtutorials website and alter that. Randomnerds Sara and Rui Santos regularly publish great content and you should check out thit site if you are not already doing that.

Recently they published a BME280based webserver, for the ESP8266 using SSE as well as one for the ESP32 and this should work on both, though I only tested it on an ESP8266.

There are more ways to skin a cat, but I will show the easiest/quickest way to change the randomnerds code to make the thermometer icon change depending on the measured temperature.

Quickly summarizing the working of the code:

  • The results of the BME280 readings are sent as ‘events’ to the webserver.
  • The webserver has some JavaScript eventhandlers that insert the readings at their proper place in the website.

So what we have to do to change the icons is:

  • Add an event
  • Add an event handler
  • Add appropriate html/css code for the webserver

As said, there are other ways of doing it, but this is the easiest to implement in the randomnerd code that I am using.

Add an event
After we get the readings of the BME280, the temperature reading is sent as an event to the webserver, inthis line events.send(String(temperature).c_str(), "temperature", millis());

We can find that line here:
right under that we will add another server event:
if (temperature <10) {
events.send("<i class='fas fa-thermometer-quarter' style='color:#0000ff;'></i>","warm", millis());
events.send("<i class='fas fa-thermometer-half' style='color:#059e8a;'></i>","warm", millis());

As wordpress sometimes garbles code a bit, it should look like this

This code checks if the temperature is below 10 degrees and if yes sends a piece of html that defines a new icon (fa-thermometer-quarter) and the color red. It sends that in an event with the name ‘warm’
If it is 10 degrees or higher, it restores the ‘old’ icon and color. If you want that to be a blue color the colour code should be ff0000 rather than ‘059e8a’.

Where can we find that extra icon we need:

Have a look at the HTML and CSS code. The icons that are used are found in a “style sheet” on the “awesomefonts.com” website. As it is on an external website, we call it an “external style sheet” and the code links to it with the following statement found in the heading of the HTML code:
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css"

Checking the awesome font website, we can find a low temperature thermometer icon. I picked “fa-thermometer-half”

Event handler
Now we need to add an Eventhandler that knows what to do with the event.
We find the event handlers in the <script></section> section of the webserver. The one handling the temperature looks like this:
Right under that we will be adding another event handler that handles our ‘warm’ event. That one should look like so:
What this code does is it listens for the event called ‘warm’ and then prints it to the ‘console’ that is the console in your browser(F12) and it is useful for error checking, you can delete the line, it is not essential.
The document.getElementByID instruction then inserts the data that was sent with the event into an HTML ‘element’ that has an id that is also called ‘warm’ (you may give that another name if you wish).

Adapting the HTML code
The icon is called in the body of the webpage with the following code:
<i class="fas fa-thermometer-half" style=color:#059e8a;"></i>"

(picture shows it as well)
The ‘i’ element that is used here is the html code for ‘italics’, but it is often used as an element in which to define icons as well.

As we are using theĀ  document.getElementByID instruction all we need to do is to use an identifier (called “warm”) for the piece of text we want to replace.
We do that by putting ‘<span id="warm"> <span> around the section we want to replace, like this:
But remember to keep the surrounding code on that line intact, like this
Here you will find a complete code that also has a card added for the voltage and has dynamic icons for temperature, Atmospheric Pressure and Voltage. It has a static IP.