Mein Python MQTT Tutorial soll dir in ein paar Beispielen zeigen, wie du ganz leicht MQTT-Nachrichten mit Python senden und empfangen kannst. Die Grundlagen habe ich bereits in meiner MQTT Raspberry Pi Einführung vorgestellt. Diese Python MQTT Einführung soll dir jedoch darüber hinaus weitere Funktionen und Anwendungsbeispiele verdeutlichen.
Inhaltsverzeichnis
- MQTT mit dem Raspberry Pi und dem ESP8266
- Was ist MQTT?
- Quality of Service Levels
- Python MQTT Bibliothek
- Kostenlose MQTT Broker
- MQTT Nachrichten empfangen
- MQTT Nachrichten versenden
- MQTT Last Will Nachricht konfigurieren
- Mit Nutzername und Password am Broker anmelden
Weitere MQTT Tutorials
Ich habe bereits zwei weitere MQTT-Tutorials hier veröffentlicht. Eines für den Raspberry Pi und eines für den NodeMCU ESP8266. Dort gehe ich auf bereits auf ein paar der Punkte ein, die ich in diesem Guide erkläre. Sieh dir die beiden Tutorials auf jeden Fall an, wenn du den Raspberry Pi oder ESP8266 mit MQTT in dein Smarthome integrieren möchtest!MQTT Grundlagen
Bevor mit der Programmierung des Tutorials begonnen wird, möchte ich die Grundlagen des MQTT-Standards erklären.Was ist MQTT?
Bei MQTT handelt es sich um ein Publish-Subscribe-Messaging-Protokoll. Beim Publish-Subscribe-Modell gibt es Themen, die abonniert (subscribe) und auf denen Daten veröffentlicht (publish) werden können. Teilnehmer, die ein Thema abonniert haben, erhalten alle Daten, die auf diesem Kanal veröffentlicht werden. In der Mitte des Netzwerks befindet sich ein Broker, der als Server agiert und der die gesamte Kommunikation aller Teilnehmer verwaltet. Das Publish-Subscribe-Modell eignet sich vor allem für Anwendungen im Bereich Internet of Things, da dort sehr viele Daten gesammelt und mit anderen Geräten geteilt werden. Durch die Einteilung in einzelne Themen-Kanäle können die Daten gezielter verteilt werden. Im Smarthome wird beispielsweise für jeden Raum ein Kanal angelegt und in diesem Kanal ein Unterkanal für jedes Gerät. Ein Bewegungsmelder im Wohnzimmer würde dann seine Daten auf dem Kanal "Wohnzimmer/Bewegung" veröffentlichen. Die Lampen im Wohnzimmer können dann auf neue Daten in diesem Kanal reagieren und zum Beispiel das Licht einschalten, wenn der Bewegungsmelder eine neue Bewegung meldet. Zusätzlich zu den normalen Nachrichten, gibt es auch sogenannte Last Will Messages, die automatisch versendet werden können, wenn die Verbindung eines Geräts unerwartet getrennt wird. Im Smarthome kann so zum Beispiel eine Nachricht gesendet werden, wenn der Akku eines Sensors leer ist.MQTT Quality of Service (QoS)
Der MQTT-Standard verfügt über drei unterschiedliche "Qualitätsstufen" (Quality of Service oder QoS). Sie geben an, wie zuverlässig die Zustellung der Nachrichten ist. Die verfügbaren QoS-Levels:- Nachricht kommt höchstens einmal an (0)
- Nachricht kommt mindestens einmal an (1)
- Nachricht kommt genau einmal an (2)
QoS Level 0: Nachricht kommt höchstens einmal an
Das unterste Quality of Service Level im MQTT-Standard garantiert nicht, dass die Nachrichten auch ankommen. Vielmehr wird eine Nachricht gesendet und nicht geprüft, ob die Nachricht auch ankommt. Geht die Nachricht aufgrund von Verbindungsabbrüchen oder sonstigen technischen Problemen verloren, wird sie nicht erneut gesendet. Das QoS-Level 0 eignet sich also im Smarthome in den meisten Fällen nicht für den produktiven Einsatz, da nicht sichergestellt ist, dass die Nachrichten auch ankommen. Dabei könnten beispielsweise Sensorwerte verloren gehen oder Geräte nicht auf Schaltbefehle reagieren.QoS Level 1: Nachricht kommt mindestens einmal an
Das nächst-höhere Level besitzt bereits eine Prüfung, ob die gesendete Nachricht auch beim Empfänger angekommen ist. Dies geschieht durch eine Bestätigung des Empfängers, die an den Absender der Nachricht geschickt wird. Falls jedoch die Empfangsbestätigung verloren geht, sendet der Absender die Nachricht solange erneut, bis er eine Empfangsbestätigung empfängt. Dieses QoS-Level eignet sich beim Einsatz im Smarthome in den meisten Fällen für alle Schaltbefehle. Falls beispielsweise die Nachricht "Flur-Licht an" doppelt gesendet wird, geht das Licht an und die doppelte Nachricht ändert nichts daran. Lediglich bei Toggles (z.B. Licht umschalten) kann es zu Problemen führen, wenn eine Nachricht doppelt gesendet wird. Der erste Befehl schaltet hier das Gerät zum Beispiel an, während der zweite Befehl das Gerät sofort wieder ausschalten würde. Für das Loggen von Sensorwerten macht das QoS-Level 1 nur wenig Sinn, da Sensorwerte dann doppelt gespeichert werden könnten. Abhilfe schafft hier das QoS-Level 2.QoS Level 2: Nachricht kommt genau einmal an
Ähnlich wie das QoS-Level 1 besitzt auch Level 2 eine Empfangsbestätigung - jedoch wird die Empfangsbestätigung ebenfalls bestätigt und die komplette Transaktion damit abgeschlossen. Geht eine der Bestätigungen dabei verloren, so wird die ursprüngliche Nachricht erneut gesendet, jedoch mit dem Hinweis, dass es sich um ein Duplikat handelt. Der Empfänger kann diese Nachricht dann ignorieren, wenn er sie beim ersten Versuch bereits empfangen hat und anschließend seine Empfangsbestätigung senden. Diese Prozedur wird so oft wiederholt, bis alle Empfangsbestätigungen empfangen wurden. Somit eignet sich das QoS-Level 2 also auch für Toggles oder den Versand von Sensorwerten, da Duplikate von Nachrichten entsprechend gekennzeichnet sind und so nicht zu doppelten Daten führen.Welches Quality of Service Level soll ich verwenden?
Im Smarthome dürfte das QoS-Level 0 in nahezu keinem Anwendungsfall Sinn machen, da nicht garantiert werden kann, dass die Nachricht überhaupt ankommt. QoS-Level 1 hingegen reicht für alle Befehle aus, die einen festen Status setzen ("Gerät x an", "Heizung auf 25°C", "Lampe auf 100%"), jedoch weniger für das Loggen von Sensordaten oder Toggle-Befehle ("Lampe umschalten"), da das potenzielle doppelte Senden dieser Befehle den Status verfälscht. QoS-Level 2 eignet sich dagegen am besten für das Loggen von Sensorwerten und Toggle-Befehle, da sichergestellt ist, dass jede Nachricht genau einmal empfangen wird.MQTT-Client für Python 2
Um den MQTT-Client für Python Version 2.x zu installieren, führst du die folgenden Befehle auf der Kommandozeile aus:sudo apt-get install python-pip -y
sudo pip install paho-mqtt
MQTT-Client für Python 3
Falls du Python Version 3.x verwendet, führst du hingegen die folgenden Befehle auf der Kommandozeile aus:sudo apt-get install python3-pip -y
sudo pip3 install paho-mqtt
Kostenlose MQTT Broker
Es gibt ein paar kostenlose und öffentliche MQTT-Broker, die du zum Testen von deinen Projekten benutzen kannst:- mqtt.eclipse.org
- broker.hivemq.com
Für den produktiven Einsatz solltest du daher unbedingt einen eigenen MQTT-Broker verwenden. Ich habe hier bereits ein Tutorial veröffentlicht, dass dir erklärt, wie du einen Raspberry Pi als MQTT-Broker einsetzen kannst:
MQTT Nachrichten mit Python empfangen
Das erste Skript, dass erstellt werden muss, ist das Empfänger-Skript. Es abonniert Nachrichten aus einer bestimmten Topic und gibt alle Nachrichten aus, die darauf veröffentlicht werden. Für dieses Tutorial benutze ich den öffentlichen MQTT-Broker von HiveMQT.[/vc_column_text]Für das Empfänger-Skript fügst du den folgenden Code in deine IDE ein und führst ihn aus:# !/usr/bin/python
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
TOPIC = "home/tutorial/PubSubDemo"
BROKER_ADDRESS = "broker.hivemq.com"
PORT = 1883
def on_message(client, userdata, message):
msg = str(message.payload.decode("utf-8"))
print("message received: ", msg)
print("message topic: ", message.topic)
def on_connect(client, userdata, flags, rc):
print("Connected to MQTT Broker: " + BROKER_ADDRESS)
client.subscribe(TOPIC)
if __name__ == "__main__":
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER_ADDRESS, PORT)
client.loop_forever()
MQTT Nachrichten mit Python verschicken
Als nächstes wird ein Skript erstellt, das eine Nachricht auf dem Topic "home/tutorial/PubSubDemo" mit dem QoS-Level 1 veröffentlicht. Füge einfach den folgenden Code ein und führe ihn aus (das erste Skript muss ebenfalls aktiv sein):# !/usr/bin/python
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
TOPIC = "home/tutorial/PubSubDemo"
BROKER_ADDRESS = "broker.hivemq.com"
PORT = 1883
QOS = 1
if __name__ == "__main__":
client = mqtt.Client()
client.connect(BROKER_ADDRESS, PORT)
print("Connected to MQTT Broker: " + BROKER_ADDRESS)
DATA = "{TEST_DATA}"
client.publish(TOPIC, DATA, qos=QOS)
client.loop()
Last Will Nachricht
Der MQTT-Standard ermöglicht es auch, andere Geräte zu benachrichtigen, wenn ein Gerät die Verbindung verliert. Dies ist möglich durch die sogenannte Last Will-Message (deutsch: Letzter Wille). Diese Nachricht kann vom Client gesetzt werden und wird dann vom Broker an alle Subscriber einer definierten Topic gesendet. Im Smarthome-Einsatz ließe sich damit etwa das Gateway benachrichtigen, dass ein Gerät die Verbindung verloren hat.Last Will Nachricht senden
Im folgenden Beispiel zeige ich dir, wie du mit Python ganz einfach eine Last Will Message per MQTT versenden kannst.Als Empfänger wird wieder das Skript aus dem ersten Abschnitt dieses Tutorials verwendet. Die Last Will Nachricht wird dann auf dem entsprechenden Topic veröffentlicht.Der andere Client setzt auf der Topic "home/tutorial/PubSubDemo" als Last Will Message die Nachricht "Verbindung beendet!", verbindet sich dann mit dem Broker und veröffentlicht danach die Nachricht "Hello World!" auf der selben Topic. Als Quality of Service wird Level 1 verwendet, alle Nachrichten kommen also mindestens einmal beim Empfänger an. Verliert er die Verbindung, so veröffentlicht er also die Nachricht "Verbindung beendet!" auf dem Kanal "home/tutorial/PubSubDemo". Um dies zu simulieren, wird das Skript beendet, ohne die Verbindung zum Broker ordnungsgemäß zu beenden. Dies sorgt dafür, dass der Broker die Last Will Message auf dem entsprechenden Topic veröffentlicht.# !/usr/bin/python
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
TOPIC = "home/tutorial/PubSubDemo"
BROKER_ADDRESS = "broker.hivemq.com"
PORT = 1883
QOS = 1
if __name__ == "__main__":
client = mqtt.Client()
LAST_WILL = "Verbindung beendet!"
client.will_set(TOPIC, LAST_WILL, qos=QOS, retain=False)
client.connect(BROKER_ADDRESS, PORT)
print("Connected to MQTT Broker: " + BROKER_ADDRESS)
DATA = "{TEST_DATA}"
client.publish(TOPIC, DATA, qos=QOS)
client.loop()
Verbindung zu einem MQTT-Broker mit Zugangsdaten
Damit nicht jeder Zugang zu den veröffentlichten Nachrichten bekommt, ist es möglich, verschiedene Topics mit einem Nutzernamen und einem Passwort zu schützen. Um dich mit deinem Python-Skript an einem geschützten Broker anzumelden, kannst du einfach das folgende Code-Snippet verwenden und die entsprechenden Zugangsdaten einsetzenclient = mqtt.Client()
client.username_pw_set("my_username", "my_password")
Fazit
Ich hoffe, dass dir mein Python MQTT Tutorial einen guten Einblick in das MQTT-Protokoll geben konnte!Dieser Beitrag hat dir gefallen?
Dann abonniere doch unseren Newsletter!