{"id":121,"date":"2021-05-14T16:48:55","date_gmt":"2021-05-14T14:48:55","guid":{"rendered":"https:\/\/www.iot-embedded.de\/iot-2021\/?p=121"},"modified":"2021-05-14T16:48:56","modified_gmt":"2021-05-14T14:48:56","slug":"mqtt-mit-python","status":"publish","type":"post","link":"https:\/\/www.iot-embedded.de\/iot-2021\/smart-drive\/mqtt-mit-python\/","title":{"rendered":"MQTT mit Python"},"content":{"rendered":"<p>Da die Software f\u00fcr die IoT-Devices in Python entwickelt wird, m\u00fcssen MQTT-Nachrichten aus Python heraus versendet und empfangen werden k\u00f6nnen. Dazu wird der Paho-MQTT-Client f\u00fcr Python verwendet.<\/p>\n<h2>Installation<\/h2>\n<p>Die Installation erfolgt mittels pip, dem Package Manager f\u00fcr Python. Damit das Paket nicht systemweit installiert wird, wird zun\u00e4chst eine virtuelle Umgebung angelegt und aktiviert.<\/p>\n<pre class=\"block\">python -m venv mqtt\nsource mqtt\/bin\/activate\n<\/pre>\n<p>Die Installation wird mit folgendem Befehl ausgef\u00fchrt.<\/p>\n<pre class=\"block\">pip install paho_mqtt\n<\/pre>\n<p>Das Paket kann nun innerhalb der virtuellen Umgebung verwendet werden.<\/p>\n<h2>Verbindung zum Broker herstellen<\/h2>\n<p>Unabh\u00e4ngig davon, ob Nachrichten empfangen oder versendet werden, ist eine Verbindung zu einem Broker notwendig. Damit die Verbindung hergestellt werden kann, muss der Hostname bzw. die IP-Adresse des Brokers sowie der verwendete Port bekannt sein. Zu Testzwecken wurde ein Broker ohne Authentifizierung aufgesetzt.<\/p>\n<p>Damit eine Instanz des MQTT-Client erzeugt werden kann, muss zun\u00e4chst die oben installierte Bibliothek importiert werden.. Anschlie\u00dfend kann die <i>connect<\/i>-Methode der Instanz mit den Verbindungsparametern aufgerufen werden. Damit die ge\u00f6ffnete Verbindung gehalten wird und auf eingehende Nachrichten \u00fcberwacht wird, muss eine Schleife verwendet werden, die verhindert, dass das Skript weiterl\u00e4uft und beendet wird. Daf\u00fcr bringt der Client verschiedene Methoden mit, deren Namen mit <i>loop<\/i> beginnen. Die einfachste Variante ist die Methode <i>loop_forever<\/i>, die den Ablauf des Skripts an der Stelle ihres Aufrufs solange h\u00e4lt, bis durch den User abgebrochen wird.<\/p>\n<p>Damit die Verbindung zum Broker nach Abbruch ordnungsgem\u00e4\u00df getrennt wird, l\u00e4uft die Schleife in einem <i>try<\/i>-Block. Zum Beenden kann Strg+C verwendet werden.<\/p>\n<pre class=\"block\">import paho.mqtt.client as mqtt\n\nclient = mqtt.Client()\nclient.connect(\"193.41.237.111\", 1883, 60) # Daten des Brokers\n\ntry:\n\tclient.loop_forever()\nfinally:\n\tclient.disconnect()\n<\/pre>\n<p>Dies ist ein Minimalbeispiel und wird in den folgenden Schritten erweitert.<\/p>\n<h2>Subscribe<\/h2>\n<p>Das oben gezeigte Minimalbeispiel h\u00e4lt zwar eine Verbindung zum Broker, ist jedoch soweit nutzlos, da der Client f\u00fcr kein Topic registriert ist und somit keine Nachrichten empf\u00e4ngt. Um direkt nach dem Verbindungsaufbau ein Topic zu abonnieren, kanndem Client eine Handler-Methode \u00fcbergeben werden. Diese wird nach Aufbau der Verbindung aufgerufen. Im Rumpf dieser Methode wird neben einer Meldung zum Status der Verbindung dann ein Topic abonniert. Dadurch werden alle Nachrichten dieses Topic empfangen.<\/p>\n<pre class=\"block\">def on_connect_handler(client, userdata, flags, return_code):\n\tprint(\"Return Code: \" + str(return_code))\n\tclient.subscribe(\"iot\")\n<\/pre>\n<p>Um empfangene Nachrichten zu verarbeiten, wird eine weitere Handler-Methode ben\u00f6tigt. Diese wird beim Empfang einer Nachricht aufgerufen und gibt das Topic sowie den Inhalt der empfangenen Nachricht aus.<\/p>\n<pre class=\"block\">def on_message_handler(client, userdata, message):\n\tprint(message.topic)\n\tprint(str(message.payload))\n<\/pre>\n<p>Wird nun wieder die Methode <i>loop_forever<\/i> des Client aufgerufen, wird jede empfangene Nachricht auf der Konsole ausgegeben. Das gesamte Skript sieht so aus:<\/p>\n<pre class=\"block\">import paho.mqtt.client as mqtt\n\ndef on_connect_handler(client, userdata, flags, return_code):\n\tprint(\"Return Code: \" + str(return_code))\n\tclient.subscribe(\"iot\")\n\ndef on_message_handler(client, userdata, message):\n\tprint(message.topic)\n\tprint(str(message.payload))\n\nclient = mqtt.Client()\nclient.on_connect = on_connect_handler\nclient.on_message = on_message_handler\nclient.connect(\"193.41.237.111\", 1883, 60)\n\ntry:\n\tclient.loop_forever()\nfinally:\n\tclient.disconnect()\n<\/pre>\n<p>Die reine Konsolenausgabe der Nachrichten dient hier zu Demonstrationszwecken. F\u00fcr einen Anwendungsfall m\u00fcssen die Daten nat\u00fcrlich verarbeitet werden.<\/p>\n<h2>Publish<\/h2>\n<p>Im obigen Beispiel wurde zwar das Topic <i>iot<\/i> abonniert, jedoch werden keine Nachrichten empfangen, solange kein Client in diesem Topic Nachrichten ver\u00f6ffentlicht. Deshalb folgt hier das Skript f\u00fcr einen anderen Client, der Nachrichten ver\u00f6ffentlicht. Im sp\u00e4teren Anwendungsfall werden dies vor allem die IoT-Devices sein.<\/p>\n<p>Der Client muss zun\u00e4chst mit dem selben Broker wie der empfangende Client verbunden werden. Anschlie\u00dfend werden in einer Schleife solange Nachrichten ver\u00f6ffentlicht bis das Skript beendet wird. Im Beispiel wird alle 10 Sekunden die aktuelle Zeit ver\u00f6ffentlicht.<\/p>\n<pre class=\"block\">import paho.mqtt.client as mqtt\nfrom datetime import datetime\nfrom time import sleep\n\nclient = mqtt.Client()\nclient.connect(\"193.41.237.111\", 1883, 60)\n\ntry:\n\twhile True:\n\t\tpayload = datetime.now().strftime('%Y-%m-%d %H:%M:%S')\n\t\tclient.publish(\"iot\", payload=payload)\n\t\tprint(\"Ver\u00f6ffentliche in iot: \" + payload)\n\t\tsleep(10)\nfinally:\n\t\tclient.disconnect()\n\t\tprint(\"Verbindung getrennt\")\n<\/pre>\n<p>Startet man nun die beiden Skripte parallel, sieht man wie einerseits Nachrichten ver\u00f6ffentlicht werden und andererseits die gleichen Nachrichten empfangen werden. Beide Skripte k\u00f6nnen mit Strg+C beendet werden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Da die Software f\u00fcr die IoT-Devices in Python entwickelt wird, m\u00fcssen MQTT-Nachrichten aus Python heraus versendet und empfangen werden k\u00f6nnen. Dazu wird der Paho-MQTT-Client f\u00fcr Python verwendet. Installation Die Installation erfolgt mittels pip, dem Package Manager f\u00fcr Python. Damit das<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[8],"tags":[],"_links":{"self":[{"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/posts\/121"}],"collection":[{"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/comments?post=121"}],"version-history":[{"count":5,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/posts\/121\/revisions"}],"predecessor-version":[{"id":126,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/posts\/121\/revisions\/126"}],"wp:attachment":[{"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/media?parent=121"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/categories?post=121"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/tags?post=121"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}