The thinger.io 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!
Sounds good? Let’s see how to make a real-time dashboard!
Hardware
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 thinger.io 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
ThingerWifi thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
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;
mag.getEvent(&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: http://www.magnetic-declination.com/
// 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() {
thing.handle();
}
// 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
//From: http://forum.arduino.cc/index.php?topic=3922.0
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!