Seit etwas über einem halben Jahr überwache ich jetzt mein Raumklime mit Naemon und Grafana. Die ganze Zeit habe ich die Daten über einen Raspberry Pi gesammelt, an dem ein DHT22 Sensor angeschlossen war.
Nun habe ich das umgebaut, auf einen NodeMCU mit ESP8266 Chip.
Hier nochmal der Link, zum alten Beitrag.
Der ESP8266 kann, dank seines WLAN Chips, die Aufgabe des Raspberry Pi perfekt übernehmen. Dabei umgehe ich dann auch gleich das Problem, das die SD-Karte des Raspberry Pi früher oder später versagen wird.
Schaltplan
Der Schaltplan ist sehr einfach und auch hier finden sich wieder unzählige Beispiele im Internet. Das Gute ist, dass der DTH22 mit 3.3 Volt und 5 Volt Arbeiten kann.
Wichtig: Nicht den 4,7kΩ Pullup-Widerstand vergessen. Ihr könnt diese Library verwenden.
Daten abfragen
Die Daten (Temperatur und Luftfeuchtigkeit) frage ich über einen Web Server auf dem ESP8266 ab. Anstelle von HTML gibt dieser die Daten als XML zurück. Die Abfrage macht wieder ein Naemon Plugin, welches in PHP geschrieben ist.
Die magic number *0.8 wie beim Raspberry Pi benötige ich beim ESP8266 übrigends nicht mehr.
Naemon übernimmt jetzt wieder die Überwachung für mich, und schickt mir eine Benachrichtigung aufs Handy, sobald die Luftfeuchtigkeit zu hoch ist.
Darstellung in Grafana
An der Darstellung der Daten habe ich nichts verändert. Diese erfolgt weiterhin über Grafana.
WLAN Stabilität
Obwohl der ESP8266 nur eine sehr kleine Antenne hat, habe ich überhaupt keine Probleme mit dem WLAN Signal. Ganz im Gegenteil. Ich habe einmal in den Graph geschaut, der die WLAN Verbindung vom Monitoring zum ESP8266 überwacht.
Es sieht so aus, als ob sich Round Trip Time und Packet Loss deutlich verringert haben, seitdem ich den ESP8266 nutze - im Vergleich zum Raspberry Pi mit einem WLAN USB Stick
Ausbau
Da der ESP8266 so schön billig ist, habe ich mir mitlerweile für mehre Räume kleine "Messstationen" gebaut. Besonders praktisch, im Schlafzimmer nutze ich den FireTV zur Stromversorgung und benötige so kein eigenes Netzteil.
Programmcode
Den größten Teile habe ich einfach aus dem Beispiel ESPWiFiWebServer
für das NodeMCU übernommen.
Ich habe lediglich den WLAN Access Point deaktiviert, und die DHT Sachen mit eingebaut.
Die Antwort habe ich von HTML auf XML umgebaut.
// DHT22 Struct
struct Humidity {
int humidity;
unsigned int humidityFrac;
int temperature;
unsigned int temperatureFrac;
};
#include <ESP8266WiFi.h>
#include "DHT.h"
const char* ssid = "EUER_WLAN_NAME_HIER";
const char* password = "EUER_SUPER_WLAN_PASSWORT_HIER";
#define DHTTYPE DHT22
const int DHTPin = 5;
DHT dht(DHTPin, DHTTYPE);
//Static IP
IPAddress ip(192, 168, 1, 6);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
dht.begin();
// prepare GPIO2
pinMode(2, OUTPUT);
digitalWrite(2, 0);
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
//Disable WiFi AP
WiFi.mode(WIFI_STA);
//Set Static IP
WiFi.config(ip, gateway, subnet);
//Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.println(WiFi.localIP());
}
void loop() {
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.println("new client");
while(!client.available()){
delay(1);
}
// Read the first line of the request
String req = client.readStringUntil('\r');
Serial.println(req);
client.flush();
Humidity humidity = getHumidityAndTemperature();
Serial.print("Humidity: ");
Serial.print(humidity.humidity);
Serial.print(".");
Serial.print(humidity.humidityFrac);
Serial.println("%");
Serial.print("Temperature: ");
Serial.print(humidity.temperature);
Serial.print(".");
Serial.print(humidity.temperatureFrac);
Serial.println("*C");
// Prepare the response
String response = "HTTP/1.1 200 OK\r\nContent-Type: application/xml\r\n\r\n<?xml version='1.0'?><document>";
response += "<humidity>";
response += humidity.humidity;
response += ".";
response += humidity.humidityFrac;
response += "</humidity>";
response += "<temperature>";
response += humidity.temperature;
response += ".";
response += humidity.temperatureFrac;
response += "</temperature>";
response += "</document>\n";
// Send the response to the client
client.print(response);
delay(1);
Serial.println("Client disonnected");
// The client will actually be disconnected
// when the function returns and 'client' object is detroyed
}
Humidity getHumidityAndTemperature() {
struct Humidity humidityStruct;
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
humidityStruct.humidity = int(humidity);
humidityStruct.humidityFrac = (humidity - int(humidity)) * 100;
humidityStruct.temperature = int(temperature);
humidityStruct.temperatureFrac = (temperature - int(temperature)) * 100;
return humidityStruct;
}