Quellen: H. Baumgärtner, P. Kraut, R. Rahm, ZSL Esslingen, 2021
Ch. Götz, D. Obermaier, "PUB/SUB for the masses - An introduction to MQTT", Internet of Things Conference, 2014
J.-P. Mens, "MQTT dient dem Admin für viele ungewöhnliche, aber nützliche Anwendungen", Linux Magazin, 11/2015
W. Kimmig, J. Schnaiter, Gewerblich-Technische Schule Offenburg, 2022
Im Internet der Dinge werden physische Objekte im Internet vernetzt. Dies bedeutet bspw. das Sensordaten im Internet bereitgestellt werden oder Aktoren aus dem Internet gesteuert werden.
Um die Sensordaten im Netz bereitzustellen benötigen wir:
Das Wifi-Modul befindet sich auf der Oberseite des ESP 8266. Für die Wifi-Verbindung müssen wir die Bibliothek wifi.py
einbinden. Diese beinhaltet die notwendige Funktion für den Verbindungsaufbau mit SSID und Passwort des Wifis:
from wifi import wifiConnect
# Zugangsdaten WLAN
ssid = "iotWifi"
password = "piuserwifi"
#Verbindungsaufbau WIFI
wifiConnect(ssid, password)
Der Wifi-Verbindungsaufbau wird in einer eigenen Methode def wifiConnect(ssid, password)
ausgelagert. Diese startet den Verbindungsaufbau und wartet in einer while-Schleife solange, bis die Verbindung steht.
Bei erfolgreichem Verbindungsaufbau wird am Ende der Methode die SSID und die IP-Adresse ausgegeben.
MQTT ist ein schlankes offenes IoT-Netzwerkprotokoll für die direkte Kommunikation zwischen Geräten im Netzwerk. Nachrichten benötigen eine geringe Bandbreite und funktionieren auch auf eingeschränkten Geräten. Für MQTT-Nachrichten ist der Port 1883 reserviert.
Clients verbinden sich mit einem Server, dem sogenannten MQTT-Broker und können Nachrichten publizieren (publish) oder Nachrichten abonnieren (subscribe) und so auf das Eintreffen von Nachrichten warten. Später werden wir einen Broker auf dem Raspberry Pi installieren. Zu Beginn arbeiten wir einfach mit dem öffentlichen Broker HiveMQ (broker.hivemq.com). Der Broker empfängt, verwaltet und versendet alle Nachrichten.
Im Gegensatz zu HTTP gibt es kein Polling durch den Client, sondern der Broker informiert den wartenden Client, sobald eine Nachricht vorliegt. Damit nicht jeder jede Nachricht erhält, werden die Nachrichten anhand von Topics unterschieden und ein Broker kann diese anhand von Access Control Listen (ACL) regeln.
Nachrichten sind sogenannte Payloads, welche häufig als einfache Strings versendet werden: "T = 23 °C"
. Will ein Client eine Temperatur vom Wohnzimmer im EG erfahren, abonniert er die Topics: temperatur/wohnen/eg
. Mit temperatur/+/eg
abonniert er alle Temperaturen im EG und mit temperatur/wohnen/#
abonniert er die Temperatur aller Wohnzimmer. Man beachte, dass +
für eine Topic Ebene steht und mehrfach verwendet werden darf, während #
für diese und alle folgenden Ebenen steht und einmalig verwendet wird. Ob ein Client alle Nachrichten sieht entscheidet allerdings die Broker-ACL.
Benötigte Software:
Der MQTT Explorer ist ein MQTT Client, mit dem Topics gesendet, empfangen und visualisiert werden können.
MQTTool ist ein MQTT Client für IOS.
MQTT Dash ist ein MQTT Client für Android.
Für die MQTT-Verbindung müssen wir die Bibliothek mqtt.py
einbinden. Diese beinhaltet die Klasse MQTTClient
für den Verbindungsaufbau mit dem Server und sowohl zum veröffentlichen als auch zum abbonieren von Nachrichten. Im ersten wollen wir uns auf das veröffentlichen von Nachrichten beschränken.
from machine import I2C, Pin
from wifi import wifiConnect
from mqtt import MQTTClient
from bmp180 import BMP180
import time, json
# Zugangsdaten WLAN + MQTT
ssid = "iotWifi"
password = "piuserwifi"
server = "broker.hivemq.com"
topic = b'eg/wohnen'
#Objekte erzeugen
client = MQTTClient(server, keepalive=60)
i2c = I2C(scl=Pin(5), sda=Pin(4))
bmp = BMP180(i2c, 100100.0) #Tagesluftdruck in Pascal
#Verbindungsaufbau WIFI und MQTT
try:
wifiConnect(ssid, password)
client.mqttConnect()
except OSError as e:
print('Failed to connect to Local Network or MQTT broker.')
print('Reconnecting...')
time.sleep(10)
machine.reset()
while True:
#Messwerte auslesen und speichern
messwerte={
"pressure": bmp.pressure/100.0,
"temperature": bmp.temperature
}
#MQTT versenden
print(messwerte)
client.mqttPublish(topic, json.dumps(messwerte));
time.sleep(5)
Neben den Modulen machine
, time
und json
müssen wir die Bibliotheken wifi
und mqtt
importieren um eine Netzwerkverbindung aufzubauen. Zusätzlich benötigen wir ggf. für jeden Sensor eine entsprechende Bibliothek.
Im zweiten Schritt definieren wir unsere Zugangsdaten für das WLAN und MQTT. Als Zugangsdaten benötigen wir einerseits die Adresse des MQTT-Brokers. Darüber hinaus definieren wir das Topic unter dem wir die Messwerte später versenden.
Bevor wir mit dem Verbindungsaufbau beginnen können erzeugen wir uns drei Objekte:
MQTTClient
mit dem Servernamen als Parameter. Hinweis die Client-ID wird zufällig erzeugt, da diese immer einzigartig sein sollte.I2C
mit Pinnummer als Parameter für die Daten- und Steuerleitung.BMP180
für den hier beispielhaft verwendeten Luftdruck- und Temperatursensor.Der eigentliche Verbindungsaufbau findet in einem try-except-Block statt. Im try-Block wird der Code auf Fehler getestet. Im except-Block wird dann ggf. der Fehler behandelt. In diesem Fall wird die Wifiverbindung und die Verbindung zum MQTT-Broker aufgebaut. Falls es zu einem Fehler kommt wird der ESP-Controller neu gestartet.
Die Messwerte werden nun zyklisch abgerufen und in einem Dictionary zwischengespeichert. Zum Versenden von Nachrichten über das Netzwerk müssen wir nun nur noch die Methode client.mqttPublish(topic, messwerteImJsonFormat)
mit den beiden Parametern: Topic und Messwert im JSON-Format aufrufen.
JSON ist eine Notation in der Daten in einem kompakten Format bereit gestellt werden. Das Format ist unabhängig von der Programmiersprache und die Datei erhält die Endung "json".
{
"Temperatur": 21.8,
"Luftfeuchte": 32.0
}
Ein JSON-Dokument beginnt und endet mit der geschweiften Klammer. Jeder Schlüssel steht in Anführungszeichen und nach einem Doppelpunkt folgt der Wert des Schlüssels. Für die Werte gibt es unterschiedliche Datentypen.
"Mustermann"
21.8
[23, 21, 25]
{..}
null
{
"Name": "Mustermann",
"Vorname": "Max",
"Alter": 23,
"Hobbys": ["MTB", "Ski", "Lesen"],
"Kinder": [],
"Adresse":
{
"Straße": "Musterstr. 8",
"Ort": "71289 Musterstadt"
}
}
In der Notation sind die Absätze nicht erforderlich, erleichtern aber die Lesbarkeit. Wir können die Methode json.dumps(messwerte)
nutzen um die Daten eines Python-Dictionaries in das JSON-Format zu bekommen. Der Vorteil besteht nun darin, dass die Daten im MQTT-Explorer visualisiert werden können und die Daten so direkt in eine Datenbank exportierbar sind.
messwerte={
"pressure": bmp.pressure/100.0,
"temperature": bmp.temperature
}
client.mqttPublish(topic, json.dumps(messwerte));
json_dict = json.loads(json_string)
.
Ein Programm für das versenden von MQTT-Nachrichten (publish) wird geschrieben, verifiziert, kompiliert und auf den ESP-Mikrocontroller geladen.
XML ist eine Notation in der Daten in einer hierarchischen Struktur bereitgestellt werden. Die Daten werden in sogenannten Elementen in einer Baumstruktur angeordnet und in einer Datei mit der Endung "xml" gespeichert..
<!-- Ich bin die Kopfzeile -->
<?xml version="1.0"?>
<!-- Ich bin das Wurzelelement -->
<kunden>
<!-- Ich bin ein Element mit Attribut -->
<kunde id="1">
</kunde>
</kunden>
Alle Elemente werden bis auf die Kopfzeile wie bei HTML in ein öffnendes und schließendes Tag geschrieben. Dabei hat jedes Dokument ein Wurzelelement und es können Attribute in Elementen vergeben werden. Auch Kommentare sind möglich.
<?xml version="1.0"?>
<clients>
<client id="1">
<firstname>John</firstname>
<surname>Doe</surname>
<born>23.09.1992</born>
<address>
<street>232 Washington</street>
<city>San Diego</city>
<zip>92101</zip>
</address>
</client>
</clients>
DOM ist ein Standard der W3C, um auf XML-Dokumente zuzugreifen oder sie zu verändern. DOM stellt ein XML-Dokument als Baumstruktur dar und besteht aus Knoten.
WiFi | WLAN-Standard (engl. wireless fidelity) |
SSID | Name des Wifi |
MQTT | MQTT ist ein IoT-Netzwerkprotokoll für die direkte Kommunikation zwischen Geräten im Netzwerk (engl. Message Queuing Telemetry Transport) |
der MQTT-Broker | empfängt und verteilt die MQTT-Nachrichten |
der MQTT-Client | kann MQTT Nachrichten abbonieren und publizieren, wenn er mit dem Broker verbunden ist |
die JSON-Notation, -en | JavaScript Object Notation ist ein kompaktes Datenformat. |
die XML-Notation | Extensible Markup Language ist eine hierarchisch strukturierte Notation von Daten. | Document Object Model
Document Object Model | Das Document Object Model (DOM) ist ein Standard für XML-Dokumente. |