MQTT è un protocollo di messaggistica leggero che consente ai dispositivi di inviare piccoli messaggi attraverso un server centrale, chiamato broker, invece di comunicare direttamente tra loro. Un dispositivo pubblica un messaggio sotto un'etichetta chiamata topic, e ogni programma iscritto a quel topic ne riceve una copia. È per questo che MQTT si trova nei sensori, nei gateway industriali, negli hub Zigbee e nei sistemi degli edifici.

Andy Stanford-Clark di IBM e Arlen Nipper, allora in Arcom Control Systems, lo progettarono nel 1999 per monitorare oleodotti tramite collegamenti satellitari lenti e costosi. Questa origine spiega ancora oggi molte delle sue caratteristiche, dai pacchetti minuscoli alla possibilità per un dispositivo di predisporre l'annuncio della propria scomparsa dalla rete.

In breve

  • MQTT usa il modello pubblicazione/sottoscrizione: i dispositivi pubblicano messaggi sui topic di un broker, che li inoltra a tutti gli iscritti interessati.
  • Chi pubblica e chi si iscrive non devono conoscersi. Si può quindi aggiungere una dashboard, un database o un servizio di allerta in seguito senza modificare il dispositivo.
  • Tre livelli di QoS permettono di bilanciare banda e garanzie di consegna, mentre il testamento segnala quando un dispositivo perde la connessione.
  • Sparkplug aggiunge a MQTT una struttura comune dei topic, un formato dei dati e il monitoraggio dello stato online/offline per i sistemi industriali.

A cosa serve MQTT?

MQTT si usa dove molti dispositivi comunicano spesso piccole quantità di dati e un sistema deve reagire. Esempi tipici sono una sonda che invia ogni minuto la temperatura di una cella frigorifera, un controllore che segnala se una pompa è in funzione o un hub Zigbee che inoltra eventi di apertura porte e movimento. La stessa connessione funziona anche nell'altro senso: un'applicazione può inviare un comando a un dispositivo, per esempio per commutare un relè o modificare un setpoint.

Tre caratteristiche spiegano perché è adatto a questi compiti. Anzitutto, i dati aggiuntivi sono pochissimi: l'intestazione fissa di un pacchetto MQTT può occupare appena due byte, mentre una richiesta HTTP contiene normalmente alcune centinaia di byte di intestazioni prima della lettura vera e propria. Quando un dispositivo invia un numero ogni pochi secondi, la differenza si accumula.

La connessione, inoltre, rimane aperta. Poiché è stato il dispositivo ad avviarla verso l'esterno, il broker può inviargli messaggi anche se si trova dietro un firewall o su una rete mobile che bloccherebbe le richieste in ingresso.

Infine, mittente e destinatari sono indipendenti. Un sensore che pubblica su un topic non sa se lo ascolta un programma o venti. Aggiungere una dashboard o un servizio di allerta un anno dopo non richiede quindi modifiche al firmware del sensore.

Molti apparecchi che vale la pena monitorare non supportano MQTT in modo nativo. Contatori di energia e azionamenti usano spesso Modbus, i controllori degli edifici BACnet, le macchine industriali espongono OPC UA e molti sensori wireless per edifici usano Zigbee. La soluzione abituale è un gateway sul posto che legge il protocollo originario e pubblica i valori come messaggi MQTT. Può essere un dispositivo industriale Advantech o Moxa, un piccolo computer con Node-RED oppure un hub Zigbee2MQTT che pubblica in JSON i dati di ogni dispositivo Zigbee. Da quel momento, il resto del sistema deve comprendere un solo protocollo.

MQTT non è la risposta a ogni esigenza. HTTP è spesso più semplice per scambi occasionali di richiesta e risposta, come un dispositivo che carica un rapporto al giorno o un'applicazione che recupera un file di configurazione. Un sensore a batteria progettato per durare anni in genere non può mantenere aperta una connessione TCP. Usa quindi una radio a basso consumo, come LoRaWAN, e raggiunge il resto del sistema attraverso un gateway. Anche lo streaming video e il trasferimento di file grandi richiedono altri protocolli.

Che cos'è un server MQTT?

Un server MQTT è il programma a cui si collegano tutti i dispositivi e le applicazioni. Viene normalmente chiamato broker perché non distribuisce pagine come un server web. Riceve ogni messaggio, ne legge il topic e ne consegna una copia a ciascun client con una sottoscrizione corrispondente. Tra i broker più noti ci sono Eclipse Mosquitto, open source, EMQX e HiveMQ, oltre a servizi cloud come AWS IoT Core.

I topic sono stringhe di testo divise in livelli da barre, un po' come i percorsi dei file. Una sonda di cella frigorifera potrebbe pubblicare su plant1/coldroom3/temperature, un contatto porta su plant1/dock2/door. Nessuno deve creare il topic in anticipo: esiste nel momento in cui qualcuno vi pubblica. Per questo i team concordano presto una struttura dei nomi. Il broker accetta qualsiasi grafia, e un refuso diventa semplicemente un nuovo topic che nessuno ascolta.

Gli iscritti possono usare due caratteri jolly. Il segno più corrisponde esattamente a un livello: plant1/+/temperature riceve quindi le temperature di tutte le stanze dello stabilimento 1. Il cancelletto corrisponde a tutto ciò che si trova sotto un livello: plant1/# riceve tutti i messaggi dello stabilimento 1. I caratteri jolly funzionano solo nelle sottoscrizioni; chi pubblica indica sempre un topic preciso.

Il broker non esamina il contenuto del messaggio. Il payload è soltanto una sequenza di byte: un numero, un oggetto JSON come {"temperature": 4.2, "battery": 87} oppure un formato binario. Ogni iscritto deve sapere come leggerlo. È questo il problema che Sparkplug risolve per i sistemi industriali.

Altre due funzioni del broker influenzano il comportamento del sistema. Quando un messaggio viene pubblicato con il flag retain, il broker lo conserva come messaggio mantenuto di quel topic, uno per topic, e lo invia subito a ogni nuovo iscritto. Una dashboard appena aperta può così mostrare la posizione attuale di una valvola senza aspettare l'aggiornamento successivo. Una sessione persistente permette al broker di ricordare le sottoscrizioni di un client mentre è offline e di accodare i messaggi QoS 1 e QoS 2 fino alla riconnessione. L'eventuale accodamento dei messaggi QoS 0 dipende dal broker.

Si può gestire un broker in proprio oppure usarne uno gestito da altri: il collegamento dei dispositivi MQTT a Kilo funziona in entrambi i casi. Con Cloud MQTT, Kilo predispone un broker con endpoint e credenziali propri per ciascun connettore, accettando soltanto connessioni MQTTS cifrate sulla porta 1884. Con External MQTT, Kilo si collega a un broker già in uso, come Mosquitto, HiveMQ o AWS IoT Core. In entrambi i casi si decide come associare ogni messaggio al dispositivo: attraverso uno schema del topic oppure un identificativo del dispositivo nel payload JSON.

Che cos'è un client MQTT?

Un client MQTT è qualunque elemento si colleghi al broker: un sensore, un gateway, un'app mobile, un programma che scrive in un database o una piattaforma cloud. A parte il broker stesso, il protocollo non distingue ruoli separati. Ogni client può pubblicare, iscriversi o fare entrambe le cose.

Quando si collega, il client invia un identificativo che deve essere univoco su quel broker. Se arriva una seconda connessione con lo stesso identificativo, il broker chiude la prima. È una causa frequente di due dispositivi che continuano a disconnettersi a vicenda. Il client può anche inviare nome utente e password o presentare un certificato, e dichiara un intervallo di mantenimento della connessione, per esempio 60 secondi. Se non ha nulla da inviare entro quel periodo, manda un piccolo ping per segnalare al broker che è ancora presente.

Esistono librerie client, come la famiglia Eclipse Paho, per quasi tutti i linguaggi di programmazione e per piccoli microcontrollori. Uno script Python e una scheda ESP32 possono quindi condividere un broker. Per la diagnosi dei problemi, un client MQTT desktop iscritto a # su un broker di prova mostra tutti i messaggi al loro arrivo.

Quali sono i livelli di QoS di MQTT?

La qualità del servizio, o QoS, è un'impostazione di ogni messaggio che indica a mittente e destinatario quanto impegnarsi per consegnarlo. MQTT prevede tre livelli.

  • QoS 0, al massimo una volta. Il messaggio viene inviato una volta senza conferma. Se la rete lo perde, è perso: una condizione accettabile per letture frequenti.
  • QoS 1, almeno una volta. Il destinatario conferma ogni messaggio e il mittente lo ritrasmette, in genere dopo una riconnessione, se non ha ricevuto conferma. Nulla va perso, ma un messaggio può arrivare due volte. Il destinatario deve quindi tollerare i duplicati.
  • QoS 2, esattamente una volta. Uno scambio in quattro passaggi garantisce che il messaggio venga consegnato una sola volta. Richiede il maggior numero di scambi ed è adatto quando un duplicato sarebbe dannoso, per esempio nella fatturazione per evento.

La QoS si applica separatamente a ciascun tratto: dal mittente al broker e dal broker a ogni iscritto. L'iscritto riceve ciascun messaggio al più basso dei due livelli.

Prendiamo un sensore di serbatoio che pubblica il livello di riempimento ogni 30 secondi su una connessione mobile. Con QoS 0, perdere occasionalmente una lettura non è un problema: la successiva arriva dopo 30 secondi. Un comando di chiusura di una valvola è diverso. Perderlo conta, quindi viene inviato con QoS 1 e il controllore tratta un secondo comando «chiudi» senza effetti aggiuntivi.

Che cos'è il Last Will and Testament di MQTT?

Il Last Will and Testament, di solito abbreviato in LWT e chiamato anche testamento, è un messaggio che il client affida al broker quando si collega. Contiene un topic, un payload e un livello di QoS. Il broker lo conserva e lo pubblica solo se il client scompare senza salutare: cade la rete, manca l'alimentazione o scade l'intervallo di mantenimento senza traffico. Se il client chiude correttamente la connessione, il broker elimina il testamento.

Lo schema abituale è questo. Quando un gateway si collega, pubblica online come messaggio mantenuto su plant1/gateway7/status e registra un testamento che pubblicherà offline, sempre come messaggio mantenuto, sullo stesso topic. Chiunque sia iscritto conosce così lo stato attuale del gateway, anche dopo un guasto.

La specifica concede al broker una volta e mezza l'intervallo di mantenimento prima di considerare disconnesso un client silenzioso. Con un intervallo di 60 secondi, il messaggio offline può quindi impiegare circa 90 secondi a comparire. MQTT 5, la versione attuale del protocollo, consente anche di ritardare il testamento affinché una breve riconnessione non venga annunciata come guasto.

Che cos'è MQTT Sparkplug?

MQTT Sparkplug è una specifica che definisce le regole lasciate aperte da MQTT. MQTT non stabilisce come chiamare i topic, codificare un payload o sapere se una macchina è online. Due produttori possono quindi usare MQTT senza comprendere i dati l'uno dell'altro. Sparkplug è stato creato da Cirrus Link Solutions ed è passato nel 2019 alla Eclipse Foundation, che oggi lo mantiene.

La struttura dei topic è fissa: spBv1.0/<group>/<message type>/<edge node>/<device>. I payload usano una codifica binaria compatta basata su Protocol Buffers, con metriche dotate di nome, tipi di dato e timestamp. Lo stato viene seguito mediante certificati di nascita e di morte. Quando un nodo edge va online, pubblica un messaggio di nascita che elenca tutte le metriche che trasmetterà, con nome e tipo. In seguito invia solo i valori cambiati, riducendo il traffico nei siti di grandi dimensioni. Il certificato di morte del nodo viene registrato come suo testamento MQTT. Se il nodo perde la connessione, il broker informa tutti gli iscritti senza che debbano interrogarlo.

La «B» di Sparkplug B indica la versione del formato del payload attualmente in uso. La si incontra soprattutto nelle fabbriche e nei sistemi SCADA, dove apparecchiature di più produttori condividono un broker.

Domande frequenti su MQTT

Quale porta usa MQTT?

MQTT non cifrato usa la porta TCP 1883, mentre MQTT su TLS usa la porta 8883. Entrambe sono registrate presso IANA per MQTT. Un broker può essere configurato per ascoltare anche su un'altra porta.

MQTT usa TCP o UDP?

MQTT standard funziona su TCP perché si basa su una connessione bidirezionale affidabile che conserva l'ordine dei dati. Può funzionare anche su WebSockets, permettendo a una pagina nel browser di agire da client MQTT. Esiste una variante distinta, MQTT-SN, per UDP e per le reti di sensori che non trasportano TCP.

MQTT è sicuro?

MQTT non cifra nulla da solo: la sicurezza dipende dalla configurazione del broker. Le misure abituali sono cifrare la connessione con TLS, assegnare a ogni dispositivo credenziali o un certificato client propri e limitare i topic su cui ogni client può pubblicare o iscriversi. Un broker che accetta connessioni anonime e non cifrate da Internet consente a chiunque lo raggiunga di leggere tutti i messaggi e pubblicare comandi.

Qual è la differenza tra MQTT 3.1.1 e MQTT 5?

MQTT 3.1.1 è diventato uno standard OASIS nel 2014 ed è stato poi pubblicato come ISO/IEC 20922. MQTT 5 è arrivato nel 2019 e aggiunge codici di motivo nelle conferme, scadenza di messaggi e sessioni, sottoscrizioni condivise che distribuiscono i messaggi di un topic fra più client, proprietà utente e alias dei topic. Molti broker supportano entrambe le versioni, e ogni client sceglie la propria quando si collega.

Create un connettore Cloud MQTT in un account Kilo gratuito, pubblicate una lettura JSON su TLS da qualsiasi client MQTT verso l'endpoint fornito e registrate un dispositivo per quel topic. La scheda Mapping del dispositivo elenca quindi tutti i campi inviati con il loro valore attuale. Il JSON annidato viene appiattito in chiavi come sensor.temperature, e potete scegliere quali campi diventano metriche. Un dispositivo di prova lascia spazio nel piano gratuito per altri quattro, una volta che il primo comunica correttamente.