Message Queue Telemetry Transport

Message Queue Telemetry Transport, beter bekend als MQTT is een lichtgewicht netwerkprotocol dat berichten tussen apparaten transporteert. Het is gebaseerd op het "publiceer-abonneer" concept. Het protocol werkt meestal via TCP/IP, maar elk netwerkprotocol dat geordende, verliesvrije, bidirectionele verbindingen biedt, kan MQTT ondersteunen. 

In deze tutorial leg ik kort uit wat MQTT is en hoe het werkt. Daarnaast wordt er met Python scripts een voorbeeld van het publiceren en abonneren gegeven.

MQTT-basisprincipes
MQTT is geen nieuw protocol. De eerste versie werd in 1999 gepubliceerd, maar de populariteit ervan neemt de laatste tijd sterk toe, vooral in de context van Internet of Things (IoT).

Er zijn steeds meer apparaten, sensoren, telefoons en ingebedde systemen zoals auto’s of slimme woningen die met elkaar moeten communiceren. Met de opkomst van de IoT-revolutie beleeft MQTT een tweede lente.

MQTT is een open en eenvoudig client-serverprotocol voor het publiceren van/abonneren op berichten, ontworpen voor machine-naar-machine-communicatie tussen verschillende apparaten in omgevingen met hoge latentie (vertraging) en lage netwerkbandbreedte.

Wat betekent dit? Om het duidelijk te maken splits ik de topics (onderwerpen) aan de hand van de volgende afbeelding.

MQTT-broker met de twee topics die IoT-apparaten verbinden

Machine-naar-machine communicatie
Deze is vrij eenvoudig. Het ene systeem moet informatie uitwisselen met andere systemen. In de IoT-context neemt de behoefte aan communicatie tussen apparaten enorm toe.

Alles is verbonden – in een slim huis kan je koelkast met je robotstofzuiger praten. Je kunt de lichten aandoen met je smartphone en nieuwe hondenvoer bestellen met je stem via slimme speakers.

Al deze communicatie moet mogelijk, gestructureerd, betrouwbaar en veilig zijn. Wat dit betreft worden communicatiestandaarden gedefinieerd door protocollen zoals HTTP, MQTT of andere.

Berichtentransportprotocol publiceren/abonneren
MQTT is een protocol met een speciale publiceer/abonneer-implementatie. Apparaten praten niet rechtstreeks met elkaar. In plaats daarvan is de communicatie gestructureerd in topics en afgehandeld via een centrale server (broker).

Apparaten kunnen informatie publiceren over een of meer topics. Tegelijkertijd kunnen ze zich abonneren op een of meer topics om de informatie te ontvangen die over een topic is gepubliceerd. Dit maakt een-op-veel-berichtdistributie en ontkoppeling van applicaties mogelijk.

→ Voorbeeld 1 : Bekijk de afbeelding hierboven. De smartphone kan zijn huidige positie over het topic Positie publiceren. Geïnteresseerde apparaten kunnen zich abonneren op dit topic en worden geïnformeerd wanneer een nieuw bericht wordt gepubliceerd.

Als de smartphone-positie zich buiten jouw woning bevindt, kunnen de gloeilampen en verwarmingsapparaten worden uitgeschakeld, terwijl de beveiligingscamera en de robotstofzuiger ingeschakeld kunnen worden. De smartphone hoeft niet alle apparaten apart te informeren. Het kan de informatie eenvoudig publiceren naar de centrale topic op de broker en elk apparaat dat geïnteresseerd is in de informatie kan zich hierop abonneren.

→ Voorbeeld 2 : De buitentemperatuursensor kan de buitentemperatuur publiceren in het topic Temperatuur en jouw verwarmingstoestellen kunnen zich hierop abonneren. Wanneer de buitentemperatuur onder een bepaalde waarde komt, kunnen de verwarmingstoestellen inschakelen.
Tegelijkertijd abonneert de smartphone zich op het topic om geïnformeerd te worden over de huidige binnen- en buitentemperatuur en om zijn gebruiker (persoon) hierover te informeren. De smartphone kan bovendien temperatuurregelberichten naar het topic publiceren om het verwarmingsapparaat te regelen dat ook als abonnee van het topic fungeert.

• Hoge latentie en lage netwerkbandbreedte
Het MQTT-protocol is lichtgewicht, efficiënt en bevat slechts een kleine footprint. Dit maakt het een perfecte match voor IoT-apparaten en scenario’s die vaak worden uitgevoerd in onstabiele omgevingen en gebruikmaken van onbekabelde verbindingen zoals wifi, Bluetooth of satelliet.

Nu genoeg gelezen. Laten we een voorbeeldimplementatie bekijken met behulp van Mosquitto MQTT-broker en Python MQTT-clientbibliotheek Paho-MQTT.

Voorbeeldimplementatie met Mosquitto MQTT en Python
Je kunt lokaal een MQTT-broker installeren of gratis gebruikmaken van een van de onderstaande online MQTT-brokers:

• Eclipse Mosquitto: test.mosquitto.org

• HiveMQ: broker.hivemq.com

• Eclipse IoT: broker.mqttdashboard.com

Aan de slag
Voordat we beginnen zorgen we ervoor dat alle pakketten binnen het Raspberry OS de laatste versie bevatten met:

sudo apt-get update && sudo apt-get upgrade

In dit voorbeeld gebruik ik de gratis online MQTT-makelaar Mosquitto (test.mosquitto.org) waarmee je eenvoudig verbinding kunt maken (publiceren en/of abonneren) met behulp van een MQTT-client. Als cliënt gebruiken we Python Paho-MQTT, deze kan worden geïnstalleerd met het cmd-commando:

pip install paho-mqtt && pip3 install paho-mqtt

Publiceren naar een topic
We zullen het voorbeeld uit de bovenstaande afbeelding gebruiken en twee Python-toepassingen schrijven die informatie publiceren naar het topic Temperatuur.


Binnentemperatuur
De eerste applicatie (MQTT_publisher.py) zal de binnentemperatuur over dit topic publiceren. Open nano en plaats onderstaande tekst erin en sla het script op als ‘MQTT_publisher1.py‘.

# Bibliotheken
import paho.mqtt.client as mqtt
from random import randrange, uniform
import time

# Broker bepalen
mqttBroker ="test.mosquitto.org"

# MQTT client opzetten
client = mqtt.Client("Temperatuur_Binnen")
client.connect(mqttBroker)

# Publiceren van temperatuur
while True:
    randNumber = uniform(20.0, 21.0)
    client.publish("TEMPERATUUR", randNumber)
    print("Net de waarde " + str(randNumber) + " gepubliceerd naar topic TEMPERATUUR")
    time.sleep(1)

Script analyse

# Bibliotheken laden
Eerst importeren we de Python MQTT-cliënt paho-mqtt en de bibliotheken random & time die alleen nodig zijn om dit voorbeeld te construeren.

# Broker bepalen
We moeten de locatie van de MQTT-broker definiëren. Ik gebruik de gratis online broker Eclipse Mosquitto, maar je kunt elke andere gebruiken.

# MQTT cliënt opzetten
We zetten een nieuwe MQTT-cliënt op en vragen de cliënt om verbinding te maken met de broker die eerder is opgegeven.

# Publiceren van temperatuur:
We maken een while-lus die elke seconde de huidige binnentemperatuur in het topic Temperatuur zal publiceren. De binnentemperatuur is een willekeurige float-waarde tussen 20 en 21 dat gepubliceerd wordt in het topic Temperatuur en vervolgens wordt afgedrukt op de console.

Als je het script in het console uitgevoerd wordt, ziet het er als volgt uit.

De binnentemperatuur wordt (continu) naar de broker gezonden

Buitentemperatuur
We doen weer precies hetzelfde – dit keer met de buitentemperatuur. Ik denk dat er geen verdere uitleg nodig is, alleen regel 15 verschilt van de codering hierboven die de temperatuur op een willekeurig int-getal tussen 0 en 10 zal zetten. Bovendien krijgt de cliënt een andere naam (regel 10).

Open nano en plaats onderstaande tekst erin en sla het script op als ‘MQTT_publisher2.py‘.

# Bibliotheken laden
import paho.mqtt.client as mqtt 
from random import randrange, uniform
import time

# Broker bepalen
mqttBroker ="test.mosquitto.org" 

# MQTT cliënt opzetten
client = mqtt.Client("Temperatuur_Buiten")
client.connect(mqttBroker) 

# Publiceren van temperatuur
while True:
    randNumber = randrange(10)
    client.publish("TEMPERATUUR", randNumber)
    print("Net de waarde " + str(randNumber) + " gepubliceerd naar topic TEMPERATUUR")
    time.sleep(1)

Als je het script in het console uitgevoerd wordt, ziet het er als volgt uit.

De buitentemperatuur wordt (continu) naar de broker gezonden

Abonneren op een topic
Nu is het tijd om de berichten te consumeren die zijn gepubliceerd in het topic Temperatuur. Laten we eens kijken hoe we een abonnee kunnen opzetten met Python Paho-MQTT.

Open nano en plaats onderstaande tekst erin en sla het script op als mqtt_subscribe.py

# Bibliotheken laden (client importeren)
import paho.mqtt.client as mqtt
import time

# Functie - Print ontvangen bericht
def on_message(client, userdata, message):
    print("received message: " ,str(message.payload.decode("utf-8")))

# Broker bepalen
mqttBroker ="test.mosquitto.org"

# Cliënt instellen
client = mqtt.Client("Smartphone")
client.connect(mqttBroker) 

# Lus start
client.loop_start()

# Topic waarmee cliënt verbinding moet worden
# Cliënt wordt op Topic ingeschreven
client.subscribe("TEMPERATUUR")
client.on_message=on_message 

time.sleep(30)

# Lus stop
client.loop_stop()

Sommige stappen lijken veel op de implementatie van de publicerende cliënt.

• We moeten eerst de Python MQTT-client paho-mqtt importeren. Bovendien importeren we time als een bibliotheek.
• We moeten de locatie van de MQTT-makelaar definiëren en een nieuwe MQTT-cliënt instellen die verbinding maakt met de makelaar.

De volgende stappen zijn specifiek voor de geabonneerde MQTT-clients

• Het commando client.subscribe definieert het topic waarmee verbinding moet worden gemaakt en schrijft de klant al in op het topic van de broker. Eigenlijk zullen we dan al gepubliceerde berichten ontvangen, maar we zullen er nog geen zien.
• Telkens wanneer de geabonneerde cliënt berichten ontvangt, genereert deze een on_message callback (reactie op gebeurtenis). Om de ontvangen berichten te bekijken, moeten we de on_message callback-functie specificeren en deze binnen een lus starten.


Alle drie scripts gelijktijdig starten
Het script (‘mqtt_subscribe.py’) en de andere twee scripts (‘MQTT_publisher1.py‘ en ‘MQTT_publisher2.py‘) dienen voor dit voorbeeld gelijktijdig uitgevoerd worden. Het gelijktijdig opstarten van de scripts kan eenvoudig gedaan worden door de terminal (of PuTTY (SSH)) drie keer te openen en in iedere terminal een script te starten. Zodra de eerste twee scripts informatie naar de broker zenden zal de geabonneerde de volgende informatie ontvangen.

In de praktijk kunnen het drie verschillende apparaten zijn. Je zou op drie of meer verschillende Raspberry Pi’s gelijktijdig een script kunnen laten draaien. Het enige dat van belang is dat ze allemaal van dezelfde broker en hetzelfde topic gebruik dienen te maken.

De geabonneerde ontvangt (30 sec) de binnen- en buitentemperatuur

Helaas is de consoletekst erg slecht te lezen door de omzetting van YouTube. Ik hoop dat je de bedoeling erin herkent.

Have A Nice Day!