ESP Mikrocontroller 8266

Wifi und MQTT | Messwerte im Netz bereitstellen with MicroPython



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:

  1. eine Wifi-Verbingung des ESP-Controllers,
  2. MQTT, ein Protokoll mit dem die Daten versendet werden.

connect to Wifi ESP Wifi-Verbindung

ESP 8266 mit Wifi-Modul
Abb. 1 ESP 8266 mit Wifi-Modul.

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:

  • Add-ons for your ESP
  • Python-Bibliothek:

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 Message Queuing Telemetry Transport

MQTT-Prinzip: Publisher, Broker und Subscriber
Abb. 2 MQTT-Prinzip: Publisher, Broker und Subscriber.

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.

use MQTT with your ESP MQTT Nachrichten versenden

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.

  • Add-ons for your ESP
  • Python-Bibliothek:

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:

  1. Ein Objekt der Klasse MQTTClient mit dem Servernamen als Parameter. Hinweis die Client-ID wird zufällig erzeugt, da diese immer einzigartig sein sollte.
  2. Ein Objekt der Klasse I2C mit Pinnummer als Parameter für die Daten- und Steuerleitung.
  3. Ein Objekt der Klasse 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 Notation JavaScript Object Notation

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.

  1. Zeichenkette: "Mustermann"
  2. Ganze Zahlen oder Kommazahlen: 21.8
  3. Array: [23, 21, 25]
  4. Objekte (untergeordnete Liste): {..}
  5. Nullwert: null

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));

Arbeitsauftrag 2 MQTT publish

Quelltext in der Thonny IDE zur Veröffentlichung von Sensordaten mit dem ESP-Mikrocontroller
Abb. 3 Quelltext in der Thonny IDE zur Veröffentlichung von Sensordaten mit dem ESP-Mikrocontroller.

Ein Programm für das versenden von MQTT-Nachrichten (publish) wird geschrieben, verifiziert, kompiliert und auf den ESP-Mikrocontroller geladen.

  1. Lies den Artikel "MQTT dient dem Admin für viele ungewöhnliche, aber nützliche Anwendungen" aus dem Linux-Magazin durch und notiere Dir die wesentlichen Inhalte.
  2. Installiere den MQTT-Explorer auf Deinem Rechner.
  3. Gib den Code für ein erstes MQTT-Programm in einer neuen Datei ein und speicher die Datei unter einem aussagekräftigen Namen. Das Programm soll einfach eine Nachricht übertragen.
  4. Übertrage das Programm und teste die Funktion zuerst mit dem print-Befehl. Durch Betätigen des Reset-Tasters kannst Du das Programm neu starten, um den Verbindungsaufbau zu kontrollieren. In einem zweiten Schritt abonniere das Topic am MQTT-Explorer und prüfe, ob die Daten ankommen.
  5. Erweitere das Programm so, dass mindtens zwei Messwerte übertragen werden.
  6. Speicher die Meswertdaten in einem Dictionary und wandle diese in das JSON-Format um. Wenn Du alles korrekt programmiert hast sollten die Daten im MQTT-Explorer als Diagramm darstellbar sein.

XML Notation Extensible Markup Language

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.

DOM Document Object Model

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.

XML DOM-Struktur
Abb. 4 XML DOM-Struktur.

Wichtige Begriffe zum Übertragen von Messwerten über das Netzwerk

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
Document Object Model
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 Das Document Object Model (DOM) ist ein Standard für XML-Dokumente.