Stel: je hebt allerlei Raspberry Pi’s en ESP32’s met sensoren draaien, en je wilt deze sensordata visualiseren en centraal kunnen opvragen. Hoe doe je dat? ThingsBoard biedt daarvoor een krachtig en flexibel Internet of Things (IoT)-platform aan. Je installeert het eenvoudig op je eigen server.

Koen Vervloesem

ThingsBoard is een opensource IoT-platform dat in Java geschreven is. Je kunt betalen voor de Professional Edition die op de servers van het bedrijf draait, of je kunt de opensource Community Edition op je eigen server draaien. Wij gingen met de Community Edition aan de slag en hebben deze enkele maanden geëvalueerd voor een project met Raspberry Pi’s met omgevingssensoren om de gezondheid van planten te monitoren.

Een Raspberry Pi met sensoren voor de luchttemperatuur, luchtdruk, grondvochtigheid, grondtemperatuur en lichtsterkte houdt de gezondheid van onze plant in het oog.

Installatie

ThingsBoard biedt uitgebreide installatie-instructies voor allerlei manieren: rechtstreeks op Ubuntu Server 18.04 LTS, op de Raspberry Pi met Raspbian Buster, met Docker en zelfs voor een clusteropstelling met Docker Compose of Kubernetes.

Wij voerden de installatie via Docker uit, zowel op Ubuntu 18.04 LTS als op CentOS 7. Het project biedt drie Docker-images aan: thingsboard/tb met ingebedde HSQLDB-database voor testdoeleinden, thingsboard/tb-postgres met PostgreSQL-database voor als je maar enkele berichten per seconde dient te verwerken, en thingsboard/tb-cassandra met Cassandra-database voor wie meer performance nodig heeft.

ThingsBoard is nogal hongerig voor RAM. Voor de versie met PostgreSQL-database heb je minstens 1 GB RAM nodig (het project beveelt zelfs 2 tot 4 GB aan) en voor de versie met Cassandra minstens 4 GB RAM (8 GB aanbevolen). Het project waarbij wij betrokken waren, had slechts tien Raspberry Pi’s die om de vijf minuten vijf gemeten sensorwaardes doorstuurden, dus de PostgreSQL-versie volstond. We draaiden deze succesvol op een VPS met 2,4 GHz-processor en 1 GB RAM.

ThingsBoard is een opensource IoT-platform welke je eenvoudig op je eigen server installeert.

Configuratie

We raden aan om ThingsBoard eerst eens met de standaardconfiguratie te installeren op je lokale netwerk om kennis te maken met de mogelijkheden. Na de installatie bevat ThingsBoard enkele demo-accounts met voorbeeldapparaten en -dashboards. Verander zo snel mogelijk na installatie de wachtwoorden van deze accounts in de webinterface.

ThingsBoard is tot in detail te configureren via honderden parameters, die allemaal ook als omgevingsvariabelen in te stellen zijn. Dat is ideaal voor een installatie via Docker. Zo wilden wij bijvoorbeeld MQTT en CoAP uitschakelen omdat we alleen de REST API gebruikten. Dat gaat dan eenvoudig door MQTT_ENABLED=false en COAP_ENABLED=false in te stellen.

Reverse proxy

Standaard gebruikt ThingsBoard geen HTTPS, maar je hebt wel de mogelijkheid om dit in te stellen. Voor een lokale test met zelfondertekend certificaat hebben we dat gedaan, maar voor de productie-uitrol op een publiek toegankelijke server hebben we een reverse proxy met nginx en een TLS-certificaat van Let’s Encrypt opgezet. Het Docker-image linuxserver/letsencrypt van het LinuxServer.io-team bleek daarvoor heel geschikt.

ThingsBoard draai je dan gewoon op HTTP maar zonder de poort van de Docker-container publiek toegankelijk te maken. Ons configuratiebestand voor nginx zag er dan als volgt uit:

server {
listen 443 ssl;
listen [::]:443 ssl;

server_name iot.example.com;

include /config/nginx/ssl.conf;

client_max_body_size 0;

location / {
include /config/nginx/proxy.conf;
proxy_pass http://thingsboard:9090;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}

Merk op: de regels met proxy_set_header zijn nodig om verbindingen via WebSocket te laten werken. De url http://thingsboard:9090 verwijst naar de Docker-container met de naam thingsboard die op poort 9090 ThingsBoard heeft draaien.

Dit bestand sla je dan op in /config/nginx/proxy-confs/thingsboard.subdomain.conf in de container. Het image van LinuxServer.io bevat immers al allerlei proxyconfiguraties en laadt deze dan in. Daarna is je ThingsBoard-installatie bereikbaar op https://iot.example.com.

Gebruikers

ThingsBoard kent drie soorten gebruikers: de sysadmin, tenants en customers. Elk type gebruiker heeft toegang tot andere mogelijkheden. De sysadmin beheert de hele ThingsBoard-installatie en kan tenants aanmaken en verwijderen en een mailserver instellen voor uitgaande waarschuwingen.

Het meeste zul je echter als tenant doen. In de webinterface van de tenant krijg je ook veel meer mogelijkheden. Je kunt hier “Rule Chains” aanmaken (een soort Node-RED-achtige flows waarin je visueel programmeert), customers aanmaken en beheren, apparaten en dashboards…

En uiteindelijk zijn er dan de customers. Dit zijn de eindgebruikers. Je kunt als tenant dus diverse gebruikers aanmaken die elk toegang tot andere dashboards voor apparaten hebben. Zo stel je eenvoudig in dat één gebruiker alleen sensordata van apparaten op één locatie te zien krijgt, terwijl een andere gebruiker alles mag zien.

Apparaten aanmaken

Voordat je data naar ThingsBoard kunt sturen, dien je in de webinterface een (virtueel) apparaat aan te maken voor elk apparaat waarvan je data wilt. Log daarom als tenant in en klik links op Devices. Mogelijk staan er nog demo-apparaten in, die kun je gerust verwijderen. Klik dan onderaan rechts op het rode plusteken en kies dan Add new device. Geef het apparaat een naam en een type (Sensor). Een label en beschrijving zijn optioneel. Klik op Add om het apparaat toe te voegen.

Voor grotere aantallen apparaten of een geautomatiseerde uitrol is het ook mogelijk om apparaten via de REST API aan te maken. Dat kan met een Python-script dat als tenant inlogt op ThingsBoard, een JWT access token aanvraagt en dan met deze authenticatie REST-aanroepen doet om een device van het type Sensor aan te maken, toe te kennen aan een specifieke customer en eventueel nog extra attributen zoals drempelwaarden voor sensordata aan te maken. In je code om het apparaat aan te maken, genereer je het best een cryptografisch veilig willekeurig access token van 20 alfanumerieke tekens, bijvoorbeeld als volgt:

access_token = ''.join(random.SystemRandom().choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for _ in range(20))

Sensoren aansluiten

Dan is het nu tijd om je sensoren op je Raspberry Pi aan de praat te krijgen. We tonen hier als voorbeeld hoe je een BMP280-bordje van Adafruit aanspreekt om de temperatuur en luchtdruk te meten. Dit bordje kost zo’n 12 euro en communiceert via I²C of SPI. Adafruit heeft uitgebreide documentatie op zijn website staan over hoe je dit op je Raspberry Pi aansluit en in Python aanspreekt.

Schakel eerst I²C in met sudo raspi-config en dan 5 Interfacing Options en P5 I2C. Reboot de Raspberry Pi. Installeer dan de bibliotheek van Adafruit en de bibliotheek requests voor communicatie met ThingsBoard via HTTP:

sudo pip3 install adafruit-circuitpython-bmp280 requests

Python-script

Een eenvoudig Python-script dat de temperatuur en luchtdruk van de BMP280 uitleest en die naar ThingsBoard stuurt, ziet er als volgt uit:

import json
import os

import adafruit_bmp280
import board
import busio
import requests

i2c = busio.I2C(board.SCL, board.SDA)
bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c, address=0x76)

HOST = os.getenv("IOT_THINGSBOARD_URL")
ACCESS_TOKEN = os.getenv("IOT_THINGSBOARD_ACCESS_TOKEN")
URL = f"{HOST}/api/v1/{ACCESS_TOKEN}/telemetry"

sensor_data = {}

sensor_data["temperature"] = bmp280.temperature
sensor_data["pressure"] = bmp280.pressure

payload = json.dumps(sensor_data)
r = requests.post(URL, data=payload)
print(r.text)

In het begin importeren we enkele benodigde Python-modules. Daarna maken we een I²C-busobject aan en een object voor de BMP280-sensor. Standaard gaat Adafruits bibliotheek er vanuit dat de sensor I²C-adres 0x77 gebruikt, en dan hoef je het adres niet in te voeren. Maar het exemplaar dat wij aankochten, bleek adres 0x76 te gebruiken, waardoor we een foutmelding kregen. Na de installatie van het pakket i2c-tools en even op de I²C-bus kijken met i2c-detect -y 1 ontdekten we dat de sensor op adres 0x76 werkte. Nadat we dit in de Python-code toegevoegd hadden, werkte de sensor.

De code erna haalt de url van ThingsBoard (bijvoorbeeld https://iot.example.com) en het access token van het in ThingsBoard aangemaakte device uit omgevingsvariabelen. Dat access token vind je als je in de webinterface van ThingsBoard op het apparaat klikt en dan op Copy access token. Het is een tekenreeks als TUcZIUCoEJpyzYZIHqq4. Merk op: iedereen met toegang tot dit access token kan data naar het virtuele apparaat in ThingsBoard schrijven.

Daarna maakt de code een dictionary aan en plaatst daarin de temperatuur en luchtdruk in nieuwe elementen met de sleutels “temperature” en “pressure”. Die dictionary wordt naar een JSON-string omgezet en dan als data in een HTTP POST-aanvraag naar de ThingsBoard-url doorgegeven. Die url is specifiek voor het apparaat en bevat het access token. Op het einde van dit programma zijn de temperatuur en luchtdruk dus naar ThingsBoard gestuurd en zie je ze daar bij het overeenkomstige apparaat in het tabblad Latest telemetry.

Uiteraard is deze code sterk vereenvoudigd. Er gebeurt geen enkele manier van foutenafhandeling. Als de sensor niet goed aangesloten is, of het access token ongeldig, of de website niet bereikbaar, moet de code nog correct reageren. Dat laten we als oefening aan de lezer over. Het script stuurt bovendien maar één keer data door en sluit dan af. Als je periodiek data wilt doorsturen, kun je dat in een lus doen. Maar wij kozen ervoor om een systemd-timer aan te maken die elke vijf minuten een systemd-service aanroept dat de juiste omgevingsvariabelen instelt en het Python-script dan uitvoert.

Dashboard

Deze sensordata worden nu naar ThingsBoard gestuurd, maar je wilt deze nu natuurlijk ook visualiseren. Dat kan met dashboards, een functie die ThingsBoard heel uitgebreid invult. Klik links op Dashboards. Als er nog dashboards van de demodata instaan, klik er dan gerust op om eens een voorsmaakje te krijgen van de mogelijkheden.

Een nieuw dashboard maak je door onderaan rechts op het rode plusteken te klikken en dan Create new dashboard te kiezen. Geef je dashboard een naam en optioneel een beschrijving en druk op Add. Open het zojuist aangemaakte dashboard door erop te klikken. Je krijgt No widgets configured te zien. Klik onderaan rechts op het knopje voor de edit mode.

Je krijgt nu de vraag om een nieuw widget toe te voegen, maar je kunt het best eerst nog ‘dashboard states’ definiëren. Klik linksboven op het icoontje met de twee ruitvormige vierkantjes boven elkaar (Manage dashboard states). Je ziet dat er al één dashboard state is gedefinieerd, waarbij Root state is aangevinkt. Dit is de toestand die je te zien krijgt als het dashboard wordt geopend. Je kunt nu met een klik op het plusteken rechts bovenaan een nieuwe toestand toevoegen, bijvoorbeeld voor één specifiek apparaat. Laat daar Root state afgevinkt staan. Klik na het aanmaken van deze toestand op Save en dan onderaan rechts op Apply changes.

In het dashboard van ThingsBoard kun je alle sensordata naar believen plotten.

Aliassen

In een dashboard ga je niet rechtstreeks naar een apparaat verwijzen, maar naar een ‘entity alias’. Zo’n alias kan naar één of meerdere apparaten verwijzen. Zo kun je een alias aanmaken voor alle apparaten van een specifieke klant, of van een bepaald type. Als je dan later apparaten toevoegt, past het dashboard zichzelf automatisch aan.

In de edit mode kun je die aliassen aanmaken door rechtsboven op het icoontje Entity aliases te klikken (tussen het tandwiel en de klok). Bij een alias voor meerdere apparaten schuif je de schakelaar Resolve as multiple entities naar rechts en filter je dan welke apparaten dit alias krijgen. Bij een alias voor één apparaat laat je de schuifschakelaar uitstaan en kies je als filtertype Entity from dashboard state om aan te geven dat het om een apparaat gaat dat je in het dashboard hebt geselecteerd. Vergeet niet op de knop Add en daarna op Save te klikken.

Voor elk apparaat kun je een afzonderlijk dashboard maken.

Widgets

Daarna kun je widgets toevoegen aan je dashboard. Selecteer eerst bovenaan links de dashboard state waarvoor je de widgets wilt toevoegen en klik dan op Add new widget. Het zou ons te ver voeren om ze hier allemaal te bespreken, maar ThingsBoard ondersteunt allerlei soorten widgets, zoals analoge metertjes en digitale displays, tabellen (inclusief gekleurde cellen op basis van de waarde), tijdseries en zelfs geografische kaarten. Bij elk widget kun je allerlei instellingen aanpassen, zoals de databronnen en de opmaak. Je kunt zelfs instellen welke acties er moeten gebeuren als je op een widget klikt, zoals een andere dashboard state openen met een specifiek apparaat als je op dat apparaat klikt in de lijst met alle apparaten.

Nog meer mogelijkheden

We hebben hier nog maar de basis van werken met ThingsBoard aangehaald. Bekijk zeker de online documentatie (https://thingsboard.io/docs/) om alle mogelijkheden te bekijken. Zo kan ThingsBoard ook waarschuwingen uitsturen zodra bijvoorbeeld een drempelwaarde is overschreven of een apparaat al een tijdje geen sensordata meer heeft doorgestuurd. Die functionaliteit implementeer je met de Rule Engine, een grafische interface om te programmeren op een manier die sterk aan Node-RED doet denken. En net zoals bij Node-RED kun je bij de ‘nodes’ in je ‘rule chain’ ook javascript-code invoeren. Het is een krachtige manier om op basis van inkomende data beslissingen te nemen.

De Raspberry Pi is bovendien niet het enige hardwareplatform dat je kunt inzetten om data naar ThingsBoard door te sturen. Voor toepassingen met minder stroomverbruik is er het ESP32-microcontrollerbordje. Het is zelfs mogelijk om van in de beheerinterface van ThingsBoard via het netwerk firmware-updates naar al je ESP32-apparaten te sturen.

Verder kun je naast REST ook MQTT (Message Queueing Telemetry Transport) of CoAP (Constrained Application Protocol) gebruiken als communicatieprotocol, en er zijn nog andere manieren voor integratie met externe systemen. De documentatie is niet altijd even duidelijk gestructureerd, maar met wat experimenteren zul je merken dat ThingsBoard veel mogelijkheden voor IoT-projecten heeft.

De Root Rule Chain bepaalt wat ThingsBoard met alle inkomende berichten doet.