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.

16 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
    • Hatte das gleiche Problem.
      Du hast im Lua Skript die falsche MQTT_BROKER IP Adresse angegeben (nimm die von deinem PI)

      Antworten
  2. I think I did everything as described, but something does not work.
    I describe the situation:
    In the LuaLoader monitor I see the temperature data update every 30 sec.
    in a Putty window on the Raspberry, if I type:
    mosquitto_sub -h localhost -v -t / esp8266_station123 / out
    I see the temperature data update every 30 sec.
    if in another putty window, I type:
    mosquitto_pub -d -t / esp8266_station123 / in -m „req“
    I see the request arrive at ESP8266, which immediately responds with the data I see both in the LuaLoader monitor and in the Putty window with waiting mosquitto.
    The thing that I do not get instead is that at:
    http: // openhabianpi: 8080 / basicui / app? sitemap = esp8266
    I see the layout but the temperature is not present.
    Please do you have any idea how to solve?
    Thank you

    Antworten
    • Did you find the problem, i also have the same problem now.
      The Borker seems to work (can see the data using MQTT.fx) but the temperature is not shown in the sitemap.
      Only Esp8266 Temperature -°

      Antworten
  3. Beim Aufruf der Seite
    http://openhabianpi:8080/basicui/app?sitemap=esp8266
    wird bei mir nur gemeldet: Willkommen, verfügbare Sitemaps Sie haben noch keine Sitemaps definiert.

    Die esp8266.sitemap enthält aber defintiv den Inhalt entsprechend der Codebox oben

    sitemap esp8266 label=“ESP8266 MQTT“ {
    Frame label=“ESP8266 MQTT Abfragen“ {
    Text item=ESP_Temperature

    Woran könnte das liegen?

    Antworten
      • Bei mir klappt es mit diesen Code. Diesen unter

        sitemap our_home label=“Our Home“ {

        Frame label=“ESP8266 MQTT Abfragen“ {
        Text item=ESP_Temperature

        }
        }

        diesen Code speicherst du unter
        /etc/openhab2/sitemaps/esp8266.sitemap
        Unter
        http://openhabianpi:8080/basicui/app?sitemap=esp8266
        kannst du dir dann die Sitemap angucken.

        Leider klappt bei mir noch nicht die Verbindung Broker Openhab Anzeige auf der sitemap

        Der ESP Sendet allerdings Signale an den Broker, da ich diese auch per Mqtt.fx sehen kann.

  4. Ich merke gerade, dass Openhab ein neues MQTT Binding erhalten hat (für Version 2.4) hier ist das Einbinden von MQTT Subsribtions einfacher..scheinbar.. bei mir läufts immer noch nicht.

    Antworten
  5. Servus,
    ich habe auch keine Anzeige im Openhab2.
    In der Console von openhab auf dem Raspi kommen aber die Temperaturen an.
    Was kann ich tun ?

    Antworten
  6. Hallo,

    ich habe es tatsächlich geschafft Temperatur von einem DHT22 über ESP8266 an Openhab2 zu schicken. Jetzt komme ich nicht drauf wie ich die „mqtt_connect.lua“ aus dem Beispiel so verändere um 2 Werte an das mqtt zu senden. Ich würde gerne noch die Luftfeuchtigkeit an den Openhab2 senden.
    Hoffe jemand kann mich da in die richtige Richtung schupsen.
    Gruß,
    Iwan

    Antworten
  7. Hej zusammen und danke für das Tutorial!
    Ich bekomme beim Start des ESP leider immer folgenden Fehler:

    NodeMCU custom build by frightanic.com
    branch: master
    commit: 4905381c004bdeaf744a60bb940c1906c2e052d4
    SSL: false
    modules: dht,file,gpio,mqtt,net,node,tmr,uart,wifi
    build created on 2019-05-04 10:28
    powered by Lua 5.1.4 on SDK 2.2.1(6ab97e9)
    lua: mqtt_connect.lua:19: attempt to call field ‚alarm‘ (a nil value)
    stack traceback:
    mqtt_connect.lua:19: in function ‚wait_for_wifi_conn‘
    mqtt_connect.lua:85: in main chunk
    [C]: in function ‚dofile‘
    init.lua:1: in main chunk
    [C]: ?

    Die Wifi Verbindung stellt sich trotzdem erfolgreich her. Nach meiner Recherche scheint es in meiner Firmware kein tmr.alarm zu geben?! Das tmr Paket ist ja aber definitiv drauf.
    Hat jemand eine Idee?

    Antworten
    • Siehe mein Kommentar unten:
      „Wenn jemand das 2019 probiert: die Benutzung der timer ist veraltet
      Erstellt einen timer bevor ihr ihn benutzt, erwa so:
      t = tmr.create()
      danach könnt ihr ihn so verwenden:
      t:alarm (1000, 1, function ( )
      statt delete benutzt ihr folgendes:
      t:unregister()

      Antworten
  8. Wenn jemand das 2019 probiert: die Benutzung der timer ist veraltet
    Erstellt einen timer bevor ihr ihn benutzt, erwa so:
    t = tmr.create()
    danach könnt ihr ihn so verwenden:
    t:alarm (1000, 1, function ( )
    statt delete benutzt ihr folgendes:
    t:unregister()

    Antworten

Hinterlasse einen Kommentar

Deine Email Adresse wird nicht veröffentlicht.

Blog abonnieren

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