ESP8266 mit DHT11 und Domoticz-Anbindung
Ziel war es, mit einem Temperatursensor (DHT11) und einem ESP8266 NodeMCU Temperatur und Luftfeuchtigkeit auszulesen und diese Daten auszugeben bzw. sie ebenfalls an Domoticz zu übergeben.
Dazu wurde der ESP8266 so programmiert, dass er als Webserver funktioniert und die Daten sowohl als Webseite als auch als JSON-Objekt ausgibt.
Zunächst mussten ein paar Bibliotheken in der Arduino IDE nachinstalliert werden:
- Unter „Datei“ > „Voreinstellungen“ muss „http://arduino.esp8266.com/stable/package_esp8266com_index.json“ unter „Zusätzliche Boardverwalter-URLs“ eingetragen werden.

- Anschließend muss über „Werkzeuge“ > „Board“ > „Boardverwalter…“ der ESP8266 nachinstalliert werden.

- Über den Menüpunkt „Sketch“ > „Bibliothek einbinden“ > „Bibliotheken verwalten…“ müssen die „DHT sensor library“ und die „DHT sensor library for ESPx“ nachinstalliert werden.

- Abschließend musste noch „ArduinoJson“ nachinstalliert werden.

Sind alle Bibliotheken und das Board installiert, kann mit dem Upload des Sketches fortgefahren werden.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
#include <ArduinoJson.h> #include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include "DHT.h" #define DHTTYPE DHT11 //WLAN Parameter SSID (WLAN Name) + WLAN Passwort const char* ssid = "Mein WLAN"; const char* password = "AbsolutSuperGeheim"; //Parameter für statische IP-Adresse festlegen IPAddress local_IP(192, 168, 178, x); //IP Adresse IPAddress gateway(192, 168, 178, 1); //Gateway IPAddress subnet(255, 255, 255, 0); //Subnetzmaske //Webserver Objekt erstellen mit Port 80 ESP8266WebServer server(80); //DHT11 Anschluss Pin definieren uint8_t DHTPin = D5; //DHT Objekt erstellen (Anschluss Pin, Sensortyp) DHT dht(DHTPin, DHTTYPE); //Variable für letzte Aktualisierung festlegen unsigned long previousMillis = 0; //Aktualisierungsintervall festlegen const long interval = 2000; //Variable für Temperatur und Luftfeuchtigkeit definieren float Temperature; float Humidity; void setup() { //Beginne serielle Kommunikation mit Baudrate 115200 Serial.begin(115200); //Warte 100ms delay(100); //Setze den Sensor-Anschluss-Pin in den Modus INPUT (Daten empfangen) pinMode(DHTPin, INPUT); //Starte Sensorauswertung dht.begin(); //Debug-Log über serielle Kommunikation Serial.println("Connecting to "); Serial.println(ssid); //Statische IP Adresse festlegen if (!WiFi.config(local_IP, gateway, subnet)) { //Fehler ausgeben, wenn keine statische IP Adresse zugewiesen werden konnte Serial.println("Static IP failure"); } //Verbinde mit WLAN Netzwerk WiFi.begin(ssid, password); //Verbindungsstatus überprüfen while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } //Debug-Log erfolgreiche Verbindung und Kontrolle der IP Adresse Serial.println(""); Serial.println("WiFi connected!"); Serial.print("Got IP: "); Serial.println(WiFi.localIP()); //Event definieren, wenn die IP-Adresse aufgerufen wird (http://192.168.178.x/) server.on("/", handle_OnConnect); //Event "Inline" definieren, wenn http://192.168.178.x/dht11.json aufgerufen wird server.on("/dht11.json", [](){ //Aktuelle Millisekunden merken unsigned long currentMillis = millis(); //Vergleichen, ob Differnez von (aktuellen)"Millisekunden" und "Millisekunden der letzten Abfrage" größer als das Intervall ist if (currentMillis - previousMillis >= interval) { //Wenn mindestens 2000ms vergangen sind, speichere die aktuellen ms als "Millisekunden der letzten Abfrage" previousMillis = currentMillis; //Lese Temperatur und Luftfeuchtigkeit des Sensors Temperature = dht.readTemperature(); Humidity = dht.readHumidity(); if (isnan(Humidity) || isnan(Temperature)) { //Debug-Log fehler beim Lesen Serial.println("Failed to read from DHT sensor!"); return; } //Debug-Log aktuelle Temperatur und Luftfeuchtigkeit Serial.println("Reporting " + String((float)Temperature) + "C and " + String((float)Humidity) + " % humidity"); } //Deklariere statisches JSON Dokument von 32 Byte für Ausgabe des JSON-Objektes //Potenzielle JSON-Objekt Größe berechnen: https://arduinojson.org/v6/assistant/ //Oder händisch: //"Temperature" = 13 Zeichen á 1 Byte = 13 Byte //"Humidity" = 10 Zeichen á 1 Byte = 10 Byte //Komma-Trenner = 1 Zeichen á 1 Byte = 1 Byte //2 float Werte = 2 Float á 4 Byte = 8 Byte //--------------------------------------------- // 32 Byte StaticJsonDocument<32> doc; //Werte ins JSON-Dokument schreiben doc["Temperature"] = Temperature; doc["Humidity"] = Humidity; //Finalen JSON-String deklarieren String jsonString; //JSON Objekt in den JSON-String serialisieren serializeJson(doc, jsonString); //Debug-Log JSON-String ausgeben Serial.println(jsonString); //JSON beim Aufruf von http://192.168.178.x/dht11.json (als application/json) ausgeben server.send(200, "application/json", jsonString); }); //Event für undefinierte Anfrage definiern server.onNotFound(handle_NotFound); //Server starten server.begin(); //Debug-Log, dass der HTTP Server gestartet wurde Serial.println("HTTP server started"); } void loop() { //Anfragen abarbeiten server.handleClient(); } void handle_OnConnect() { //Wenn http://192.168.178.x/ aufgerufen wurde //Lese Temperatur und Luftfeuchtigkeit vom Sensor Temperature = dht.readTemperature(); Humidity = dht.readHumidity(); //Gib HTML aus, welches in der "BuildHTML" zusammengebaut wurde server.send(200, "text/html", BuildHTML(Temperature,Humidity)); } void handle_NotFound(){ //Was ausgegeben wird, wenn eine undefinierte Anfrage kommt server.send(404, "text/plain", "Not found"); } String BuildHTML(float Temperaturestat,float Humiditystat){ //Deklariere Rückgabestring mit HTML Grundgerüst String html = "<!DOCTYPE html> <html>\n"; //HTML Header (Meta-)Informationen setzen, damit die Seite bei verschiedenen Bildschirmgrößen (z.B. Mobilgeräten) ordentlich angezeigt wird //Damit auch alle Zeichen (bzw. auch Emoticons) angezeigt werden können, wird das Character-Set auf UTF-8 gestellt html +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\" charset=\"utf-8\">\n"; //Seitentitel html +="<title>Serverschrank Temperatur</title>\n"; //Style-Eigenschaften festlegen (CSS) html +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}"; html +="body{margin-top: 50px;} \nh1 {color: #444444;margin: 50px auto 30px;}\n"; html +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n"; html +="</style>\n"; html +="</head>\n"; html +="<body>\n"; html +="<div id=\"webpage\">\n"; html +="<h1>Alex' ESP8266 NodeMCU DHT11 Serverschrank<br/>Temperaturüberwachung</h1>\n"; html +="<p>Temperature: "; html +=(float)Temperaturestat; html +="°C</p>"; html +="<p>Humidity: "; html +=(float)Humiditystat; html +="%</p>"; html +="</div>\n"; html +="</body>\n"; html +="</html>\n"; return html; } |
Anschließend konnte der ESP8266 unter der vergebenen IP-Adresse erreicht werden.

Das JSON-Objekt konnte ebenfalls ausgegeben werden.

Im Domoticz Hardware Tab wurde ein neues Gerät hinzugefügt. Hier wurde als Typ „HTTP/HTTPS poller“ gewählt. Die Methode Daten zu holen ist GET und der Datentyp, welcher geholt wird, ist „application/json“. Die URL ist jene, welche das JSON-Objekt bereitstellt, und das Intervall zur Aktualisierung setzen wir zunächst auf 30 Sekunden. Als „Kommando“ wurde das LUA-Script eingetragen, welches die Daten aufbereitet.

Abschließend musste im Hardware Tab ein virtueller Sensor erstellt werden:

Das LUA-Script, welches die Daten aufbereitet, musste ebenfalls erstellt werden. Hierzu wurde sich per SSH auf die Domoticz-Maschine aufgewählt und das entsprechende Script im Verzeichnis ~/domoticz/scripts/lua_parsers angelegt.
|
1 2 |
cd ~/domoticz/scripts/lua_parsers nano esp8266_dht11.lua |
Der Inhalt des Scripts ist folgender:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
local idx_temp = 62 local temperature = domoticz_applyJsonPath(request['content'], '.Temperature') local humidity = domoticz_applyJsonPath(request['content'], '.Humidity') local hum_stat = 0 if humidity < 30 then hum_stat=2 elseif (humidity >= 30 and humidity < 45) then hum_stat=0 elseif (humidity >= 45 and humidity < 70) then hum_stat=1 elseif (humidity >= 70) then hum_stat=3 end domoticz_updateDevice(idx_temp,0,temperature..';'..humidity..';'..hum_stat,'') |
Als idx_temp wird der Geräte Index (IDX) (!) des virtuellen Sensors aus dem Domoticz Geräte Tab verwendet. Der idx_temp legt also fest, welches Gerät upgedatet werden soll. Die Werte für Temperatur und Luftfeuchtigkeit werden aus dem JSON-Objekt extrahiert und der „hum_stat“ definiert den „Humidity Status“ den Domoticz für einen Temperatur/Luftfeuchtigkeitssensor benötigt. Dieser kann vier Werte annehmen:
- 0=Normal
- 1=Angenehm
- 2=Trocken
- 3=Nass
Und lässt sich relativ einfach ermitteln. Abschließend wird die Funktion „domoticz_updateDevice“ aufgerufen welche als Parameter den Geräteindex, nvalue, und die Werte für Temperatur, Luftfeuchtigkeit und den Luftfeuchtigkeitsstatus mitgegeben bekommt.
Am Ende wurde der Temperatursensor im Temperatur Tab angezeigt:

Ein Gedanke zu „ESP8266 mit DHT11 und Domoticz-Anbindung“