OpenHAB: MQTT Datenabfrage vom Raspberry Pi an ESP8266 NodeMCU

Der Raspberry Pi ist wie geschaffen für die Hausautomatisierung, jedoch gibt es oftmals Anwendungen, bei denen günstigere Außenposten sinnvoll sind. Dafür wollen wir den ESP8266 NodeMCU nutzen. Der Raspberry Pi fungiert dabei als Hauptstation, an den die MQTT Signale vom ESP8266 gesendet werden. Die Übertragung ist dabei sogar über andere Netzwerke / das Internet (der Dinge) möglich. Das ganze kann entweder über ein Smart Home System wie OpenHAB stattfinden, oder aber auch über das normale Raspberry Pi Betriebssystem Raspbian.

Entweder werden die Signale in einem definierten Intervall gesendet, oder aber erst auf Abfrage. Beide Szenarien werden in diesem Tutorial beschrieben und durchgeführt.

 

Zubehör

ESP8266 Mikrocontroller Board

Im Endeffekt kannst du eine beliebige Menge an Außenposten betreiben, wobei jeder anders konfiguriert werden kann und somit andere Daten verschickt. Der Einfachheit halber habe ich es jedoch lediglich mit diesen beiden Komponenten durchgeführt:

Mehr Zubehör ist nicht nötig (bis auf Stromversorgung / Batterien bzw. Powerbänke).

Auch wenn der Raspberry Pi nicht viel kostet, ist ein ESP8266 Board noch einmal wesentlich günstiger. So ist es möglich für wenig Geld an verschiedensten Orten

 

MQTT Vorbereitung: Raspberry Pi & ESP8266 NodeMCU

Wir beginnen mit dem Raspberry Pi. Falls du nicht OpenHAB zur Abfrage nutzen willst, so folge diesem Tutorial um Mosquitto zu installieren. Andernfalls starten wir mit der OpenHAB Einrichtung. Dazu muss zunächst einmal auf dem Raspberry Pi OpenHAB installiert sein.

Rufe in einem Browser deiner Wahl http://openhabianpi:8080/ auf und wähle das Paper UI aus (ggf. musst du die interne IP Adresse statt „openhabianpi“ nehmen). Unter „Add-ons“- > „Bindings“ suchst du das „MQTT Binding“ sowie unter Transformations „Regex“ und installierst diese. Das dauert einen Augenblick.

 

Weiter geht es mit dem ESP8266 NodeMCU. Wir müssen dafür eine Custom Firmware auf den NodeMCU flashen. Hierbei ist wichtig, dass das MQTT Paket ausgewählt wird (inkl. aller anderen benötigten Bibliotheken). Möchtest du bspw. einen DHT Sensor nutzen, so solltest du die entsprechende Library auch auswählen. Wichtig ist, dass die MQTT Bibliothek ausgewählt wurde.

Raspberry Pi + ESP8266 MQTT NodeMCU Custom Build

Danach flashen wir die Firmware mit dem ESP8266Flasher wie hier detailiert beschrieben.

 

MQTT Exkurs

Wie bereits im vorherigen Tutorial erklärt, wird ein Broker benötigt, um die Daten weiterzuleiten. So ein Broker kann bspw. auf dem Raspberry Pi im Hintergrund laufen. Verbundene Clients (ebenfalls Raspberry Pi’s oder eben ESP8266 NodeMCU’s) können über den Broker angesprochen werden. Der Broker sendet die Nachricht anschließend an alle verbundenen Geräte weiter.

MQTT Schema

Daten werden immer an den Broker gesendet, der widerum die Daten an alle verbundenen Subscriber published (Quelle).

 

Das Tolle daran ist also, dass wir uns nicht selbst um die Verbindung zu allen anderen Clients machen müssen. Wichtig zu wissen ist also auch, dass wenn man bspw. etwas vom Raspberry Pi an den ESP8266 senden will, dies nicht an die IP Adresse des ESP8266 sendet, sondern eben an die IP Adresse des Raspberry Pi’s (bzw. localhost), da darunter der Broker zu finden ist. Dieser leitet die Nachricht dann weiter.

 

Im Intervall ESP8266 MQTT Nachrichten an den Raspberry Pi senden

Wir beginnen mit dem Code des ESP8266. Die MQTT Subscription kann erst nachdem die Netzwerkverbindung steht, hergestellt werden. Öffne deinen ESPlorer und füge folgenden Code ein (neue Datei: „mqtt_connect.lua“):

Passe deinen Code entsprechend (SSID, IP des Brokers, Passwörter, etc.) an. Nutzt du mehrere ESP8266, so sollte jeder ein eigenes Topic bekommen (hier: „esp8266_station123“). Erstelle ggf. noch eine „init.lua“ mit dem Inhalt:

Wir lesen hier keine wirklichen Werte aus (dies kann aber ganz einfach gemacht werden). Alle 30 Sekunden wird ein Wert an den MQTT Broker gesendet. Außerdem reagieren wir auf Kommandos im „in“-Topic. Hier könnten wir z.B. verschiedene Befehle (außer „req“) definieren und unterschiedliche Werte (Temperatur, Luftfeuchte, etc.) an verschiedene Topics senden. Diese Funktion wird nur zur manuellen Anfrage gebraucht (nächstes Kapitel).

 

Weiter geht es mit dem Raspberry Pi. Wir gehen den Fall für OpenHAB durch, jedoch könnte auch einfach der Mosquitto Broker genutzt werden (Zum Senden / Empfangen ist ein Blick ins andere Tutorial hilfreich).

Zunächst einmal müssen wir die Broker Einstellungen setzen. Da wir das OpenHAB MQTT Package nutzen, müssen wir diese Konfigurationsdatei bearbeiten:

sudo nano /etc/openhab2/services/mqtt.cfg

An das Ende der Datei kommen diese Zeilen (ggf. anpassen):

broker.url=tcp://localhost:1883
broker.user=openhabian
broker.pwd=openhabian

Diese Daten (User und Passwort) müssen wir auch auf dem ESP8266 angeben. Falls du es ohne OpenHAB und bspw. Mosquitto lösen willst, so nimm die gesetzten Raspbian Logindaten (Standard Username: „pi“, Passwort: „raspberry“).

Nun erstellen wir ein Item, das die Abfrage an den ESP8266 sendet:

sudo nano /etc/openhab2/items/esp8266.items
Number ESP_Temperature "ESP8266 Temperatur [%.1f°]" { mqtt="<[broker:/esp8266_station123/out:state:REGEX((.*?))]"}

Nach dem Speichern (STRG+O, STRG+X) erstellen wir noch eine Sitemap, worin wir die Daten anzeigen lassen (oder inkludieren es in eine bestehende Sitemap):

sudo nano /etc/openhab2/sitemaps/esp8266.sitemap

Rufe nach dem Speichern die Seite auf (http://openhabianpi:8080/basicui/app?sitemap=esp8266) und sieh wie sich der Wert jede Minute verändert.

Das ganze kann natürlich auch mit Deepsleep kombiniert werden, um Strom / Batterieleistung zu sparen.

 

ESP8266 MQTT Antwort auf Anfrage des Raspberry Pi

Die andere Möglichkeit (neben dem automatischen Senden im Intervall vom ESP8266), ist die Abfrage. Dazu senden wir vom Raspberry Pi ein Signal über MQTT an den ESP8266 NodeMCU. Dieser analysiert das Signal und publishst ggf. in einem anderen Topic seinen Wert. Den nötigen ESP8266 Code haben wir bereits inkludiert (on:message).

Um ein MQTT Signal vom Raspberry Pi absenden zu können, sollten wir Mosquitto installiert haben. Das Topic, welches wir wählen ist im ESP Code definiert unter „MQTT_TOPIC_OUT“:

mosquitto_pub -d -t /esp8266_station123/in -m "req"

Anschließend wirst du sehen, wie sich der Wert in der OpenHAB BasicUI (Sitemap) aktualisiert. Wir können den Befehl auch über Rules einbinden, in dem er bspw. in einem bestimmten Intervall vom Raspberry Pi angefragt wird (und nicht vom ESP8266 gesendet wird). Das hat den Vorteil, dass wir die Daten nur dann abfragen, wenn wir sie auch wirklich brauchen.

Bei einem solchen Szenario ist aber zu beachten, dass dabei Deep Sleep nicht zu verwenden ist. Die Entscheidung ist dir überlassen.

4 Kommentare

  1. ====================================
    ESP8266 mode is: 1
    The module MAC address is: a2:20:a6:14:8a:43
    Config done, IP is 192.168.0.121
    ====================================
    failed reason: -5

    Es wird kein Wert auf der Sitemap angezeigt. Hier feheln übrigens die zwei schließende Klammern.

    Was könnte die Ursache sein?

    Antworten
    • das Problem liegt ermaß auf dem Raspberry. Ich bekomme den MQTT nicht zum laufen.
      —–
      10:25:22.861 [INFO ] [rt.mqtt.internal.MqttBrokerConnection] – Starting MQTT broker connection ‚broker‘
      10:25:22.900 [ERROR] [openhab.io.transport.mqtt.MqttService] – Error starting broker connection
      org.eclipse.paho.client.mqttv3.MqttException: Unable to connect to server
      at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:79) [215:org.openhab.io.transport.mqtt:1.11.0]
      at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:650) [215:org.openhab.io.transport.mqtt:1.11.0]
      at java.lang.Thread.run(Thread.java:748) [?:?]
      Caused by: java.net.ConnectException: Connection refused (Connection refused)
      at java.net.PlainSocketImpl.socketConnect(Native Method) ~[?:?]
      at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[?:?]
      at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[?:?]
      at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[?:?]
      at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[?:?]
      at java.net.Socket.connect(Socket.java:589) ~[?:?]
      at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:70) ~[?:?]
      —–

      Hat jemand eine Idee woran des liegt?

      Das Configfile mqtt.cfg habe ich, wie beschrieben, gefüllt.

      Antworten
    • Jetzt funktioniert die ganze Geschichte.

      geholfen, hat wie so oft, ein Neustart aller Teilnehmer.

      Was auch noch hilfreich ist, in in der Konsole dem Channel von Hand mitzuhören mit:

      mosquitto_sub -h localhost -v -t /esp8266_station123/out

      bzw. selbst einen Wert abzusetzen um zu sehen ob das Binding richtig funktioniert mit:

      mosquitto_pub -h localhost -t /esp8266_station123/out -m 5000

      Antworten

Hinterlasse einen Kommentar

Deine Email Adresse wird nicht veröffentlicht.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog abonnieren

Abonniere Raspberry Pi Tutorials, um kein Tutorial mehr zu verpassen!