MQTT

Einfache Softwarelösungen für verschiedene Probleme

Download .zip Download .tar.gz

MQTT

MQTT ist ein u.a. von IBM entwickeltes offenes Protokoll, das auf Port 1883 und 8883 (mit Verschlüsselung) läuft und für die Übertragung von Sensordaten zwischen Maschinen entwickelt wurde. Ein Artikel bei heise und ein Artikel bei dzone beschreiben das Protokoll ausführlich.

Broker

Bei der Kommunikation ist ein Broker beteiligt, der die Nachrichten empfangen und verteilen kann. Eine Implementierung für einen solchen Broker ist “mosquitto”. Er kann über den Paket-Manager installiert werden.

sudo apt install mosquitto

Für Testzwecke kann auch ein öffentlicher Broker von Eclipse verwendet werden.

MQTT_BROKER = "test.mosquitto.org"
MQTT_PORT = 1883

Clients

Mit dem Broker können nun verschiedene Clients kommunizieren. Hierbei kann ein Client ein Topic abonnieren oder Nachrichten in ein Topic schreiben.

Ein Topic ist ähnlich einer URL oder einem Dateipfad aufgebaut und verweist z.B. auf einen Sensor an einem bestimmten Ort.

TOPIC = "Ergeschoss/Wohnzimmer/Temp"

Als Client-Bibliothek für Python nutzen wir paho-mqtt. Diese lässt sich einfach installieren.

  • Windows: python -m pip install paho-mqtt oder py -m pip install paho-mqtt
  • Linux, MacOS: python3 -m pip install paho-mqtt

Subscriber

Wir beginnen mit einem Client, der ein Topic abonniert und bei neuen Nachrichten eine Ausgabe auf die Konsole macht. Hierfür geben wir zwei callback-Methoden an.

  1. my_connect_method soll aufgerufen werden, sobald eine Verbindung zum Broker zustande gekommen ist.
  2. my_message_method soll bei jeder neuen Nachricht aufgerufen werden.
import paho.mqtt.client as mqtt

def my_connect_method(client, userdata, flags, rc):
    print("Connected. Subscribing to topic", TOPIC)
    client.subscribe(TOPIC)
    
def my_message_method(client, userdata, msg):
    print("Message received:", msg.topic, msg.payload)

Nun erstellen wir einen Client und legen die eben erstellten Callback-Methoden fest.

client = mqtt.Client()
client.on_connect = my_connect_method
client.on_message = my_message_method

Schließlich verbinden wir den Client mit dem Broker und warten auf neue Nachrichten.

client.connect(MQTT_BROKER, MQTT_PORT, keepalive=60)
0

Wenn der Client verbunden ist, wird eine Endlosschleife gestartet, die regelmäßig neue Nachrichten abruft. Es gibt verschiedene Varianten, diese Netzwerkschleife zu starten, die hier genauer beschrieben werden.

  • loop_start startet den Abruf im Hintergrund,
  • loop_forever startet die Netzwerkschleife im Fordergrund und blockiert damit die Anwendung ab diesem Aufruf.
client.loop_start()
Connected. Subscribing to topic Ergeschoss/Wohnzimmer/Temp

Publisher

Erstellen wir nun einen weiteren Client, der in dem Topic Nachrichten veröffentlicht.

publisher = mqtt.Client()
publisher.connect(MQTT_BROKER, MQTT_PORT)
publisher.loop_start()

Nun können wir eine Nachricht veröffentlichen. Wir sehen die Ausgabe aus unseren definierten Callback-Methoden, sobald die Nachricht eintrifft.

publisher.publish(topic=TOPIC, payload=22)
<paho.mqtt.client.MQTTMessageInfo at 0x7f650f070360>



userdata []
userdata ['Hello', 'Hello', 'Hello', 'Hello']
[]

Userdata

Sollen Daten zwischen mehreren Nachrichten ausgetauscht werden, so kann ein userdata-Objekt hierfür genutzt werden. Es wird beim Erstellen des MQTT-Clients übergeben und wird anschließend bei jedem Eintreffen einer Nachricht automatisch mit übermittelt.

USERDATA_TOPIC = "userdata_test"

# Client mit userdata-Objekt erzeugen
a_list = []
client = mqtt.Client(userdata=a_list)

# die Methode nutzt das userdata-Objekt bei eintreffenden Nachrichten
def message_with_userdata_received(client, userdata, msg):
    my_list = userdata
    my_list.append(msg.payload.decode())
    print("userdata", userdata)

client.on_message = message_with_userdata_received
client.connect(MQTT_BROKER)
client.subscribe(USERDATA_TOPIC)
client.loop_start()

Ein Publisher wird erzeugt und verbindet sich mit dem Broker

publisher = mqtt.Client()
publisher.connect(MQTT_BROKER, MQTT_PORT)
publisher.loop_start()

Nun werden ein paar Zahlen in das Topic gesendet und dadurch die Liste in userdata gefüllt.

for i in [21,22,23]:
    publisher.publish(topic=USERDATA_TOPIC, payload=i)
userdata ['21']
userdata ['21', '22']
userdata ['21', '22', '23']

Dashboard

Ein Dahsboard für MQTT ermöglicht es, Werte im Broker zu visualisieren. Node-RED ist eine IOT-Plattform, die mit dem Raspberry Pi ausgeliefert wird.

Installation

Node-Red kann um ein Dahboard erweitert werden. Hierzu wird in Node-RED im Menü “Manage Palette” > “Install” aufgerufen. In der Suchmaske kann mit node-red-dashboard ein solches Dashboard hinzugefügt werden.

Falls der Menüpunkt nicht vorhanden ist, kann das Modul als npm-Modul über die Kommandozeile nachinstalliert werden.

    $ sudo apt install npm    
    $ cd ~/.node-red
    $ npm install node-red-dashboard

Nach einem Neustart von Node-RED, sind zusätzliche Knoten vorhanden, mit denen ein Dashboard erstellt werden kann.

Beispiel-Flow

Der folgende Flow zeigt oben einen Slider, der seinen Wert an einen MQTT-Broker sendet. Im unteren Bereich wird das gleiche Topic abonniert und der eingestellte Wert in einer Zeigeranzeige visualisiert.

flow

Eine Änderung des Schiebereglers wird nun über einen MQTT-Broker an die Zeigeranzeige weitergeleitet.

flow in action