Vai al contenuto

La piattaforma IoT ThingsBoard

In questa lezione impari a

  • capire a cosa serve una piattaforma IoT
  • creare un dispositivo e collegarlo con il suo token
  • mandare telemetria con MQTT (e con HTTP)
  • costruire una dashboard con indicatori e grafici
  • impostare un allarme

Nel laboratorio 2 abbiamo costruito un impianto IoT "fatto in casa": il nostro broker, la nostra dashboard. Funziona, ma le aziende usano piattaforme IoT già pronte, che in più salvano tutte le misure in un database, fanno dashboard con pochi clic, mandano allarmi e gestiscono utenti e permessi.

Oggi usiamo una delle più diffuse, ThingsBoard. Gira su ServerLab, il server della scuola: voi non installate niente, vi servono solo Python e il browser.

Il kit della lezione

File A cosa serve
sensore_tb.py il sensore: manda temperatura, umidità e CO₂ a ThingsBoard con MQTT
sensore_tb_http.py lo stesso sensore, ma con HTTP (se il docente vi dice che la porta 1883 è chiusa)
requirements.txt le librerie: paho-mqtt e requests

La prima volta: pip install -r requirements.txt.

ThingsBoard si apre nel browser all'indirizzo http://192.168.104.117:8080 (solo dalla rete della scuola). Il docente vi dà la vostra email e la vostra password.

Cosa cambia rispetto al laboratorio 2

  LABORATORIO 2                                LABORATORIO 3
  sensore.py ──► broker.py ──► app.py          sensore_tb.py ──► ┌─────────── ThingsBoard ───────────┐
             (nostro)     (nostra dashboard)                     │ broker MQTT · database · dashboard │
                                                                 │ allarmi · utenti                   │
                                                                 └────────────────────────────────────┘
                                                                                  ▲
                                                                           browser (voi)

Dentro ThingsBoard c'è un broker MQTT, proprio come il nostro broker.py. Il sensore funziona allo stesso modo: si collega e pubblica JSON. Cambiano solo tre cose: l'indirizzo del server, un token e il topic, che è fisso.

Passo 1: entrare e creare il dispositivo

  1. Aprite nel browser http://192.168.104.117:8080 ed entrate con la vostra email e password. Avete uno spazio tutto vostro: i compagni non vedono i vostri dispositivi e voi non vedete i loro.
  2. Nel menu a sinistra: Entità → Dispositivi.
  3. Pulsante + in alto a destra → Aggiungi nuovo dispositivo. Nome: sensore-aula. Poi Aggiungi.

Se il docente ha già creato il dispositivo per voi, sensore-aula è già nell'elenco: saltate il punto 3.

Passo 2: il token

ThingsBoard deve sapere quale dispositivo sta mandando i dati. Ogni dispositivo ha un token: una specie di password, una ventina di lettere e numeri a caso.

  1. Cliccate sul dispositivo sensore-aula: si apre il pannello dei dettagli.
  2. Pulsante Copia token di accesso.
  3. Nel kit aprite sensore_tb.py e cambiate una sola riga, quella del token:
SERVER = "192.168.104.117"           # ThingsBoard su ServerLab: già giusto, non cambiatelo
TOKEN = "INCOLLA-QUI-IL-TOKEN"       # il token del VOSTRO dispositivo

Incollate il token tra le virgolette, al posto di INCOLLA-QUI-IL-TOKEN. SERVER è già giusto.

Passo 3: mandare i dati

python sensore_tb.py

Deve comparire Collegato a ThingsBoard! e poi una riga Inviato -> ... ogni 5 secondi. Tornate nel browser, sul dispositivo, scheda Ultima telemetria: le misure arrivano e si aggiornano da sole.

Ecco le righe nuove del codice:

TOPIC = "v1/devices/me/telemetry"    # il topic fisso di ThingsBoard per le misure

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.username_pw_set(TOKEN)        # il token fa da "nome utente"
client.on_connect = collegato
client.connect(SERVER, 1883)
client.loop_start()
  • Il topic è sempre v1/devices/me/telemetry, per tutti. me vuol dire "io": è il token a dire a ThingsBoard chi è "io".
  • username_pw_set(TOKEN): in MQTT ci si può collegare con nome utente e password. ThingsBoard usa il token come nome utente, e la password non serve.
  • Il resto è il sensore del laboratorio 2: un dizionario, json.dumps, publish.
def collegato(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print("ThingsBoard ha rifiutato il collegamento:", reason_code)
        print("-> Controllate di aver copiato bene il TOKEN.")
    else:
        print("Collegato a ThingsBoard!")

Se il token è sbagliato, ThingsBoard rifiuta il collegamento (Not authorized). La callback collegato ce lo dice in chiaro.

E se la porta 1883 è chiusa?

In alcune reti la porta di MQTT è bloccata. ThingsBoard accetta le misure anche con HTTP, cioè con una normale richiesta POST, come nell'API della Bacheca. In sensore_tb_http.py il token sta dentro l'indirizzo:

URL = f"http://{SERVER}:8080/api/v1/{TOKEN}/telemetry"
risposta = requests.post(URL, json=misura, timeout=5)     # 200 = ok, 401 = token sbagliato

Il risultato su ThingsBoard è identico.

MQTT HTTP
Collegamento resta aperto una richiesta per ogni misura
Dove sta il token nome utente nell'indirizzo
Porta 1883 8080
Il server può mandare comandi al sensore? sì, subito (Missione 5) solo se il sensore glieli chiede

Telemetria e attributi

ThingsBoard distingue due tipi di dati:

  • Telemetria: misure che cambiano nel tempo (temperatura, CO₂). ThingsBoard le salva tutte, con l'ora: si possono disegnare in un grafico.
  • Attributi: informazioni "fisse" (in che aula sta il sensore, a che piano). Conta solo l'ultimo valore.

Nella Missione 4 il sensore manda anche i suoi attributi.

Se qualcosa non va

Problema Causa Soluzione
Prima incollate in TOKEN… non avete cambiato TOKEN Passo 2
Not authorized token sbagliato o incompleto ricopiatelo con Copia token di accesso
TimeoutError / ConnectionRefusedError non siete sulla rete della scuola, oppure la porta 1883 è chiusa da scuola, usate sensore_tb_http.py; da casa ThingsBoard non è raggiungibile
401 (versione HTTP) token sbagliato come sopra
Non collegato: aspetto… sempre ThingsBoard non raggiungibile chiedete al docente se il server è acceso
Le misure non compaiono state guardando un altro dispositivo il token deve essere quello di sensore-aula

Missioni

⭐ Missione 1 – Una misura in più

Aggiungete al dizionario misura di sensore_tb.py la luce (un numero a caso tra 200 e 800). Riavviate il sensore e guardate Ultima telemetria: compare la nuova misura, senza configurare niente su ThingsBoard. Perché secondo voi?

⭐ Missione 2 – La dashboard

Menu Dashboard → + → Crea nuova dashboard (nome: "Aria in aula"). Poi Aggiungi nuovo widget:

  • dalla raccolta Analogue gauges un Temperature radial gauge collegato al dispositivo sensore-aula, chiave temperatura;
  • dalla raccolta Charts un Time series chart con la chiave co2.

Salvate (icona ✓ in alto) e guardate i valori muoversi.

⭐⭐ Missione 3 – L'allarme

Fate scattare un allarme quando l'aria è viziata. Sul dispositivo, scheda Regole allarme → + → Crea nuova regola allarme: tipo di allarme "CO2 alta", condizione co2 maggiore di 1000. Aspettate che la CO₂ salga: l'allarme compare nel menu Allarmi. Aggiungete alla dashboard il widget Alarms table (raccolta Alarm widgets).

⭐⭐ Missione 4 – Chi sono

Fate in modo che il sensore, appena collegato, mandi i suoi attributi: l'aula, il piano e il tipo di sensore. Il topic è v1/devices/me/attributes e il messaggio è un JSON come per la telemetria. Controllate nella scheda Attributi del dispositivo (attributi client).

Aiutino

Dentro collegato, nel ramo else (quando il collegamento è riuscito): client.publish("v1/devices/me/attributes", json.dumps({"aula": "5A", "piano": 1})). Lo mettiamo lì perché basta mandarli una volta, all'inizio.

⭐⭐⭐ Missione 5 – La ventola, dalla dashboard

Come nel laboratorio 2, ma con ThingsBoard: dalla dashboard si manda il comando ventola al sensore, che stampa "🌀 Ventola accesa", fa scendere la CO₂ e risponde. In ThingsBoard i comandi si chiamano RPC. Per mandarli, aggiungete alla dashboard il widget RPC debug terminal (raccolta Control widgets), collegato al dispositivo: scrivendo ventola e premendo Invio il comando parte.

Aiutino

I comandi arrivano sul topic v1/devices/me/rpc/request/<numero>: iscrivetevi a v1/devices/me/rpc/request/+ (dentro collegato). Il messaggio è un JSON come {"method": "ventola", "params": {}}. Per rispondere si pubblica su v1/devices/me/rpc/response/<numero>, con lo stesso numero della richiesta: numero = msg.topic.split("/")[-1]. La risposta (es. {"ventola": "accesa"}) compare nel terminale della dashboard.

⭐⭐⭐ Missione 6 – Due aule

Create un secondo dispositivo (sensore-lab), fate una copia di sensore_tb.py con il suo token e avviatela in un altro terminale. Poi fate in modo che il grafico della CO₂ mostri le due aule insieme, con due colori.