Create Real-time IoT Dashboards!


The internet of things platform allows creating custom dashboards for monitoring different sensors and parameters in real-time. You can easily select the device, its resource (temperature, humidity, etc), and plot it in a webpage within minutes. Moreover, you can configure the sampling interval for every resource, so the device can dynamically change the reporting update as necessary. There is also another working mode that allows the device to stream the information only when it is really necessary, like a significative sensor change.

This dashboards are developed with efficiency in mind, so once you close the dashboard the device will stop sending information. You can also open the dashboard in several places (2 allowed at this moment), but the device will continue sending only once. Also, when we refer to “real” real-time, is that we use real-time WebSockets for streaming the information. We are not using other platforms approaches where devices post big HTTP requests (with headers, credentials, etc.) to a webpage with a single sensor value to later use a pooling mechanism to refresh the information. Also the devices does not send a whole HTTP request with each sample, so there is no such overhead in the information, which will save bandwidth and battery. And of course, you can modify the sampling interval just from the dashboard! Try to make something similar in other platform! :slight_smile:

Sounds good? Let’s see how to make a real-time dashboard!


In this case I will work with a NodeMCU that has some sensors attached. In particular, it has a SHT15 sensor which provides temperature and humidity. There is also a barometric pressure sensor, that will provide pressure, altitude, and temperature. Also it has attached a UV Index sensor, and a 3-Axis magnetometer that provides heading. This device with all those sensors fits in a small 400 pin breadboard, like the one in the following picture:

For this example I will be using then the NodeMCU board that is powered by the ESP8266, and the Arduino IDE for programming. But you can use any other board with Internet connectivity. So the following steps will show how to create a dashboard from scratch.

Arduino Libraries

The dashboard feature is supported by some updated capabilities in the library (both in Arduino and the Linux client that could use the Raspberry). So, please, ensure you have one of the latest libraries installed in your Arduino. At least, version >= 2.0 is required. You can check this post for reference of how to install thinger libraries in Arduino IDE.

If you enter in your Arduino Library Manager, you should see something similar to the following picture. Note that versions below 2.0 will not work with the Dashboards feature.

You also need to have installed the ESP8266 board in your Arduino IDE if you want to develop over the NodeMCU like in this post. There is also another post here for reference if you need to get this working.

Arduino Sketch

As described in the hardware section, this example will use 4 different sensors to display temperature, humidity, heading, UV index, pressure, and altitude. Two sensors are connected through I2C (magnetometer and pressure sensors), temperature & humidity is using 2 digital I/O pins, and the UV sensor index using the analog input.

The sketch will be the habitual for the Arduino projects. Include sensors headers, initialize the instances, and configure thinger instance along its resources. The good thing here is that you don’t need to make anything special to make a resource like a sensor value available to the dashboard. The resources are defined in the same way as in the previous library versions. So if you have already a device with some sensors connected, you can use it directly in the dashboard, only by updating the thinger arduino library.

The sketch used for this example is shown here for reference. But you can take the basic example from thinger libraries and add your own sensors. Notice how the code is relatively small, taking into account the functionality we will get! With around 100 lines of sketch code we will be able to expose 4 sensors to a REST API, and also make them available for real-time dashboards. If you need help about getting the credentials for your device, you can take a look to this post.

#include <SPI.h>
#include <ESP8266WiFi.h>
#include <ThingerWifi.h>
#include <Wire.h>

// SHT15
#include <SHT1x.h>

// Pressure
#include <Adafruit_BMP085.h>

// HMC5883 Magnetometer
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>

// Thinger config
#define USERNAME "username"
#define DEVICE_ID "device_id"
#define DEVICE_CREDENTIAL "device_password"

// Wifi config
#define SSID "Meeble"
#define SSID_PASSWORD "MeebleLabs"

// Specify data and clock connections and instantiate SHT1x object
#define dataPin  D1
#define clockPin D2
SHT1x sht1x(dataPin, clockPin);

// Pressure Sensor
Adafruit_BMP085 bmp;

// Analog input for UV Index
int ReadUVintensityPin = A0; //Output from the sensor

// Magnetometer
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);

// Thinger instance

void setup() {
  // initialize I2C in NodeMCU in D4 and D5
  Wire.begin(D4, D5);
  bmp.begin();  // initialize bmp sensor
  mag.begin();  // initialize magnemotemter
  pinMode(ReadUVintensityPin, INPUT); // pin mode for uv index
  pinMode(BUILTIN_LED, OUTPUT); // pin output for board led

  // initialize here thinger wifi and resources
  thing.add_wifi(SSID, SSID_PASSWORD);

  // led resource
  thing["led"] << [](pson& in){ digitalWrite(BUILTIN_LED, in ? LOW : HIGH); };

  thing["temperature"] >> [](pson& out){
    out = sht1x.readTemperatureC();

  thing["humidity"] >> [](pson& out){
    out = sht1x.readHumidity();

  thing["temp_bmp"] >> [](pson& out){
    out = bmp.readTemperature();
  thing["pressure"] >> [](pson& out){
    out = bmp.readPressure();

  thing["altitude"] >> [](pson& out){
    out = bmp.readAltitude(101500);

  thing["uv_index"] >> [](pson& out){
    int uvLevel = averageAnalogRead(ReadUVintensityPin, 8); 
    float outputVoltage = 3.3 * uvLevel/1024;
    out = mapfloat(outputVoltage, 0.99, 2.9, 0.0, 15.0);

  thing["heading"] >> [](pson& out){
    sensors_event_t event; 
    float heading = atan2(event.magnetic.y, event.magnetic.x);
    // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
    // Find yours here:
    // If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
    float declinationAngle = 0.0168715; // declination angle in radians (for madrid)
    heading += declinationAngle;
    // Correct for when signs are reversed.
    if(heading < 0) heading += 2*PI;
    // Check for wrap due to addition of declination.
    if(heading > 2*PI) heading -= 2*PI;
    // Convert radians to degrees for readability.
    out = heading * 180/M_PI;

// our loop will only call the thing handle
void loop() {

// average analog reading for more stable input
int averageAnalogRead(int pinToRead, byte numberOfReadings)
  unsigned int runningValue = 0; 
  for(int x = 0 ; x < numberOfReadings ; x++){
    runningValue += analogRead(pinToRead);
  return runningValue / numberOfReadings;  

//The Arduino Map function but for floats
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;

Starting with the Dashboards!

To work with the dashboards, please, make sure that your device is correctly connected to the platform, and you can read the resource values through the API explorer. This is required since the dashboard will use the automatic API discovery feature to easily configure the widgets, so the device must be connected when setting the dashboard.

You can configure multiple dashboards taking data from different devices. If you need help about this step, you can take a look to the following video in Youtube. But it basically consists in setting a widget type (time series chart, donut chart, google maps, MJPEG stream, value, etc), and configure the data source and its sampling interval. Sampling intervals are currently available with up to 1second resolution. You can set from 1 second to minutes or hours in this way. Use a proper sampling interval according to your requirements, so do not use always 1 second interval if it is not required. This configuration will greatly condition your power and bandwidth consumption.

Want to like more about how it works?

Here you have some ideas about how the dashboards works under the hood:

  • Your browser will open a WebSocket connection with the thinger server for each connected device. This WebSocket is used for configuring the device resources and intervals, but also for receiving sensor data. So your devices did not require to handle complex WebSockets connections.
  • All sensor data is transmitted in the normal connection between the device and the server, using the pson efficient encoding, saving bandwidth. The information is automatically converted to JSON automatically to feed the WebSocket.
  • Your sensors are only read when it is necessary (saving power). If you set a 60 seconds refresh interval, your sensor will be read only once every minute.
  • If you open two Dasboards reading the same device, the device will transmit the information only once to the thinger platform. Then this data is shared among all WebSockets at the same time.
  • If two or more dashboards set different refresh intervals for the same device resource, then the server adjust the interval automatically to the greatest common divisor. Each dashboard will receive the information at the sampling it was requested.
  • If you close the dashboard or remove a widget, the device will stop its transmission automatically.

Share your dashboards!

Please, share your dashboards and let us know what projects your are doing!


This is how the dashboards looks like in a 46 inch TV! The streaming is done from a computer using chromecast! The result is quite satisfactory! Want to see your own projects using dashboards!


me encanta la idea de compartir el uso que le estamos dando a los dashboards!
Estoy monitorizando la humedad y la temperatura de un paludario, que tiene conectados un humidificador y un ventilador que trata de mantener siempre la misma temperatura en el interior.
Hasta ahora pensaba que las variables eran relativamente estables, pero gracias a los dashboards he podido observar lo siguiente:

En la imagen se muestran la sperposición de las gráficas de temperatura (rojo) y humedad (azul) y he añadido líneas verdes par indicar el momento exacto en el que se conectan los ventiladores (verde) y el nebulizador (azul oscuro). Analizando este comportamiento he podido darme cuenta de que el comportamiento del microclima del paludario es mucho más inestable de lo esperado, los periodos duran unos 10 minutos y aunque la temperatura y humedad medias son las deseadas, las variaciones son demasiado grandes +/-1ºC y +/-7,5%.

Claramente, el margen de histéresis es demasiado grande. Lo programé así con la intención de evitar que las pequeñas variaciones, unidas a la imprecisión del DHT11 crearan un comportamiento intermitente, pero, a la vista de los malos resultados y con conocimiento de la frecuencia actual de las variables, cambiaré el programa utilizando medias de gran cantidad de lecturas (realizadas a lo largo de un minuto por ejemplo), y reduciré el parámetro de histéresis a un 3-4% en la humedad y la mitad par a la temperatura, a ver si consigo una variación de +/-0.5ºC.

El comportamiento ideal sería el siguiente:

En unos días subiré otra imagen con el resultado de los cambios!


@Alvaro … maybe you calm my tribulations …:confused:
W10, Chrome, IDE 1.6.5, ESP-1.6.5-947-g39819f0, yourlib 2.0 and 2.1, ESP-12 (plain old), old PC, old man (but capable yet I think)
Working your example ino with led, millis() and + & x I can play with led and sum 2+2 in my Devices here.
In my Dashboards working Txt with prior line showing millis(). So far reading 101790109.
Trying to use your code in this post:
I have SHT11 and BMP180 to try in Dashboards. I have 2 versions first with SHT alone and second with BMP180 alone. As you know SHT11 same as your SHT15 and BMP180 same as your BMP085
When I try to compile IDE complains saying D1 and D2 “was not declared in this scope” in SHT try and D4, D5 in the BMP try.If I try plain numbers (no prefix D) it compiles but I have not tried more and wrote this
Your advice/help … please
And thank you in advance
H.S. The afflicted


Hi! The problem that you cannot use D4 and D5 is probably that you have selected in the Arduino IDE a Generic ESP8266 Module. Try selecting the NodeMCU which includes a ESP12 and is fairly compatible with you ESP-12 (plain old). Check the pinout in this reference page so you can extract correctly the D4 (SDA) and D5 (SCL) pins for I2C for the BMP180, and the D1 and D2 (or any other pins) for the SHT15.

I recommend you to try a simple sketch before in order to check that you can read the sensors (without thinger libraries), so you can be confident that your wiring and sensors are ok. Then you can easily port the code or use the sketch in this example directly, knowing that all should be ok.

Tell me if you get it working!


@Alvaro at last Done! …I think … I hope :relaxed:
My plain old ESP12 is still alive and well one of most satisfactory $4 investment. One more time thanks to exists
I will continue to try and I have a lot of questions.
What I really want is to use Arduino (or SAMD21 when the chinese sell it - see Sparkfun yesterday’s friday products) with this ESP as WiFi shield as in another topic in this forum … but step by step one is closer …
I hope lots of people have their projects working
So as you asked I am telling you it is working


Good to know! Thanks for sharing! It is possible to write a library to use thinger through ESP8266 acting as a WiFi Shield, and it should consists on writing AT commands to connect to a Wifi Network, open a socket, and write and read data. I have to make something similar using AT commands for the SIM800 module, so I can take a look also to the ESP8266. Will keep working on it! :relaxed:


sorry! I forgot this post!
After introducing some changes in the hysteresis code, and using an averaging sensor reading, I succeed to get a more accurate behavior. Now the temperature is stable and the humidity cycles becomes more constant.


I tried to associate a resource that i am using to stream in real time to a widget using “sampling interval” as refresh mode besides associating the same to another widget using “Update by device” mode. Both the widgets are displaying same data. Why is it so? Am i missing something basic?


Hy ymgupta!
To improve performance, server selects the same interval to refresh all widgets from same resource, ussing always the smallest of all. I’m afraid that, to make what you are triying, you need to use different resources.


Hi , Can you save or retrieve your dashboards? Like saving today’s dashboard so you can review it on some other time.
Any reply or help would be appreciated.
Thank you.


First of all, this is the best platform out there for IoT beginners. So thank you for creating this and maintaining it.

Second, I am looking at building a custom widget like a heat map within my dashboards, the data is uploaded as an X-Y array. Wondering if we can incorporate a custom dashboard externally?



is it we do it on a local network server? or it need to connect with online server?
i mean that is a local server? or online server? or Both of them?


Both of them. You can deploy it locally or use it on our cloud. Check our home page for downloads.


can you link it here?


which platform required for local service?
can i use local mode on a ESP8266 Stand alone Without any Server?


You can install server in your own Ubuntu server. Then connect your ESP8266 devices also to your own server. Check out the downloads section in the homepage.