Eine Statusanzeige/Ampel fürs SmartHome

Manchmal möchte man Informationen aus dem SmartHome in der realen Welt darstellen. Gerade für Kinder oder weniger technisch versierte Familienmitglieder ist dies praktisch bis notwendig. In meinem Fall ist dies beim Warmwasserbestand der Fall. Im Winter, wenn das Warmwasser der Solarthermie nicht mehr reicht, wird das Warmwasser nur auf Bestellung erwärmt, um unnötiges Aufheizen und Abkühlen im Warmwasserspeicher zu beschränken.

Im Winter und auch in den Übergangszeiten kommt es dann aber immer wieder zu der Frage: ist Warmwasser da? Diese Frage beantwortet inzwischen eine kleine Ampel im Bad, welche sich die Information aus dem SmartHome – besser gesagt direkt aus Node-RED über eine HTTP Schnittstelle – bezieht.

Hardware

Technische Basis bildet ein Wemos D1 mini (ESP8266) mit einem RGB LED SHIELD. Dazu noch eine kleine Powerbank (ein Werbegeschenk) und ein Schalter, damit er keine Steckdose blockiert.

Der Wemos D1 mini ist extrem einsteigerfreundlich, da er direkt über MicroUSB geflasht werden kann.

Software

Für die Software nutze ich einen Arduino IDE Sketch, den ich für meine Zwecke mit der Zeit immer weiter verfeinert habe.

Und so funktioniert der Sketch grob

  • sobald der D1 mini Strom hat, verbindet er sich mit dem definierten WLAN, während des Verbindungsversuch blinkt die LED lila
  • nach der erfolgreichen Verbindung mit dem WLAN fragt er die eingestellte URL ab und bekommt als Antwort eine Zahl zwischen 1 und 3, die für eine der drei Farben der Ampel steht
  • die LED des Shields zeigt die entsprechende Farbe
  • bei Fehlern leuchtet die LED weiß
  • alle 30 Sekunden wird die Schnittstelle neu abgefragt und die Farbe aktualisiert

Die komplette Logik liegt beim SmartHome – der Wemos D1 mini ist bei mir ein reines Ausgabegerät. In meinem Fall bedeutet 3, dass genug Warmwasser da ist – die Ampel/LED zeigt grün. Bei 2 wird das Warmwasser langsam knapp – gelb. Und die 1 bedeutet – wer hätte es anders erwartet – eine kalte Dusche (die rote Ampel hat dich gewarnt).

Natürlich könnte man auch einen Sensorwert abfragen und die Zuordnungen von Farben zu Messwert den Wemos D1 mini machen lassen. Für mich erschien die Möglichkeit, die entsprechenden Schwellen später ohne neues Flashen der Ampel ändern zu können, komfortabler.

Schnittstelle zu Node-RED

Der Flow in Node-RED ist bei mir richtig öde, aber sei hier doch aufgrund der Vollständigkeit erwähnt. An anderer Stelle wird der Warmwasserbestand schon für Dashboard/UI ausgewertet. Daher greife ich auf die vorgefertigten Daten zurück und gebe sie nach dem Request auf das HTTP-in Node einfach aus.

Und hier mein Sketch

(Immer wenn im Code ein xx steht, musst du etwas „persönliches“ eintragen. An anderen Stellen sicher auch.)

#include <Adafruit_NeoPixel.h> 
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

#define PIN D2 //RGB LED Chip auf dem Digitalen PIN D2

const char* ssid = "xx";
const char* password = "xx";

IPAddress staticIP(192, 168, xx, xx); //ESP static ip
IPAddress gateway(192, 168, xx, xx);   //IP Address of your WiFi Router (Gateway)
IPAddress subnet(255, 255, 255, 0);  //Subnet mask
IPAddress dns(192, 168, xx, xx);  //DNS

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(1, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
    Serial.begin(115200);
    WiFi.hostname("xx");
    pixels.begin(); //initialisieren
    WiFi.config(staticIP, subnet, gateway, dns);
    WiFi.begin(ssid, password);
    WiFi.mode(WIFI_STA); 
    while(WiFi.status() != WL_CONNECTED){
        Serial.println(".");
        pixels.setBrightness(15); 
        pixels.setPixelColor(0, pixels.Color(255, 0, 255)); 
        pixels.show(); //Aktualisieren des NeoPixels
        delay(100);
        pixels.fill(0x000000);
        pixels.show();
        delay(100);
    }
  
    Serial.println(millis()); 
}

void loop() {
  if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
     WiFiClient client;
     HTTPClient http;
     http.begin(client, "http://192.168.xx.xx:1880/arduino/ww");
     int httpCode = http.GET();
  
     if(httpCode == 200) {
        String payload = http.getString();
        if(payload == "1") {
           pixels.setPixelColor(0, pixels.Color(255, 0, 0)); 
           Serial.println("Kein Warmwasser da");
        }
        else {
           if(payload == "2") {
              pixels.setPixelColor(0, pixels.Color(255, 255, 0));         
              Serial.println("Wenig Warmwasser da");
           }
           else {
              pixels.setPixelColor(0, pixels.Color(0, 255, 0));          
              Serial.println("Genug Warmwasser da");
           }
        }
     }
     else {
        Serial.println("Error on HTTP request");
        pixels.setPixelColor(0, pixels.Color(255, 255, 255));          
     }
     
     http.end();
     pixels.show(); //Aktualisieren des NeoPixels
  }
  delay(30000);
      pixels.setPixelColor(0, pixels.Color(255, 0, 255)); 
      pixels.show(); //Aktualisieren des NeoPixels
      delay(300);
}

Hinweise

  • Die Vergabe einer festen IP beschleunigt den Verbindungsversuch um ein paar Millisekunden, kann man machen, muss man aber nicht.
  • Die LED des Shields ist sehr hell, ich habe die Helligkeit daher deutlich reduziert.
  • Über die serielle Schnittstelle (Baud 115200) ist der Sketch sehr gesprächig.