Smarte Bad-Sparheizung mit ESP

Dieser ergänzende Online-Artikel zeigt die Konfiguration der Software im Detail.

vorlesen Druckansicht
Lesezeit: 11 Min.
Von
  • Jan Kipping
Inhaltsverzeichnis

Die Einrichtung von Home Assistant als Smarthome-Zentrale wurde schon in Make 1/21 sowie auf heise+ ausfĂĽhrlich beschrieben, deshalb beschreibe ich im Folgenden nur die notwendigsten Schritte, um ESPHome mit einem vorhandenen Home Assistant zu nutzen und das in der Make-Ausgabe 6/22 ab Seite 20 beschriebene System aufzusetzen.

Ich verwende das Home Assistant Operation System und die aktuelle ESPHome-Version 2022.10.4. Der gesamte Code für dieses Projekt liegt auf Github, es ist also nicht unbedingt nötig, die beschriebenen Schritte noch mal zu Fuß zu machen, wenn man keine eigenen Modifikationen vornehmen will.

ESPHome ist ein Add-in in Home Assistant, das ĂĽber Einstellungen/Add-ins installiert und gestartet wird.

Anschließend taucht es in Home Assistant in der linken Navigationsleiste auf. Für diesen Artikel nutze ich den Wizard – der ist okay, insbesondere wenn man noch nie ESPHome genutzt hat.

Mit + New Device wird der neue Knoten angelegt. Danach auf Continue drücken, das Flashen auf das Gerät erfolgt später. Anschließen den Namen (etwa bad-infrarotheizung) angeben und weiter.

Wie erwähnt: Für alles folgende liegt auf dem Github von Make ein vollständiges Beispiel, es ist also nicht unbedingt nötig, jeden nachfolgend beschriebenen Schritt im Detail nachzuvollziehen. Wer schon öfters ESPHome genutzt hat, kommt so schneller weiter.

Nun muss das Board ausgewählt werden. Ich verwende hier das Wemos D1 mini, und wähle das auch als spezifisches Board aus. Für dieses Projekt kann allerdings so ziemlich jedes ESP-Board verwendet werden, falls noch ein abweichendes rumliegt.

Als nächstes Skip auswählen, denn es empfiehlt sich, noch ein paar grundlegende Sachen vor dem ersten Flashen einzustellen. Nun kann man die Konfiguration des Knoten mit Edit anpassen. Der Editor ist interaktiv, das heißt: Potenzielle Fehler erkennt er beim Editieren, dabei werden auch ungeeignete Belegungen der Prozessorpins gefunden. Superpraktisch.

Wenn man die vom Wizard erstellte Datei öffnet, ist schon einiges vorausgefüllt. Es gibt normalerweise keinen Grund, an dieser etwas zu ändern. Erklärungen zu den Einträgen findet man in der Dokumentation auf ESPHome.io.

Passwörter in Konfigurationsdateien sind selten eine gute Idee. Home Assistant wie auch ESPHome lagern daher Passworte in separate Dateien aus. So kann man Konfigurationen sorgenfrei teilen und zeigen.

Falls dies das erste ESPHome-Projekt ist, muss man sein WLAN-Passwort in die Datei secrets.YAML eintragen. Dazu den Editor schlieĂźen, rechts oben auf Secrets drĂĽcken (siehe Bild) und die Daten einfĂĽgen.

Jetzt endlich können wir den Knoten an das Projekt anpassen.

Als erstes vergebe ich immer eine feste IP-Adresse. Das beschleunigt das debuggen sehr, da nicht erst der Name aufgelöst werden soll und mDNS-Pakete durch Multicast das WLAN verstopfen.

Dazu wird im Key wifi eine manuelle Adresse hinzugefĂĽgt:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    # Set this to the IP of the ESP
    static_ip: 192.168.178.242
    # Set this to the IP address of the router. Often ends with .1
    gateway: 192.168.178.1
    # The subnet of the network. 255.255.255.0 works for most home networks.
    subnet: 255.255.255.0  

Danach lohnt es sich zu wissen, ob der WLAN-Empfang am Einsatzort gut genug ist. Meine Familie findet Schalter, die nur manchmal oder manchmal nicht funktionieren, sind: nicht lustig.

Der WLAN-Sensor gibt den RSSI-Pegel an:

sensor:
  - platform: wifi_signal
    name: "bad-infrarotheizung_WiFi_Signal"
    update_interval: 30s
    entity_category: "diagnostic"
    filters:
      - sliding_window_moving_average:
          window_size: 15
          send_every: 2
      - or:
          - delta: 2
          - throttle: 10min

Ein paar Erklärungen zum Code:

In ESPHome ist alles, was keine binären Werte ausgibt, ein Sensor. Der YAML-Key sensor: darf dabei nur einmal vorkommen, alle anderen Sensoren, die später noch dazukommen, müssen aufeinander folgen. Zur Erinnerung: in YAML kann ein Key mehrere Values haben, aber die müssen eben zusammen im Code stehen.

Der Sensor wird im update_interval so konfiguriert, dass er jede halbe Minute aktualisiert wird.

Da sich in Home Assistant irgendwann zu viele sinnlose Werte in der Datenbank sammeln, wird die Übertragungsrate mit Filtern angepasst. Erst wird ein arithmetischer Mittelwert über 15 Werte erstellt, um das Rauschen zu entfernen. Der or-Filter mit delta und throttle stellt sicher, dass große Signaländerungen (hier eine RSSI-Differenz von der letzten Übertragung größer 2) sofort gesendet werden, ansonsten alle 10 Minuten. Die Kategorie (entity_category: "diagnostic") räumt später das Frontend auf, damit der Wert nicht so prominent angezeigt wird, da er für Heizung selbst nicht verwendet wird.

Der erste Flashvorgang muss in der Regel per Kabel erfolgen. Dazu wird der Knoten per USB an den Rechner angeschlossen.

Zum Flashen ist dann Chrome oder Edge nötig, da nur diese Browser eine serielle Verbindung zum COM-Port unterstützen. Wer das nicht möchte, kann auch den ESP auch direkt an den Pi anschließen und die entsprechende Option wählen.

Das erste Flashen ist manchmal hakelig: Der Bootloader passt nicht, die Baudrate stimmt nicht oder was auch immer. Wenn es nicht klappt, hilft es nach einem Reset bis zum Prepare-Vorgang den Bootknopf zu drĂĽcken.

Sobald das Flashen gelungen ist, wird der Knoten entweder automatisch in der Integrationen-Seite aufgeführt, oder muss wie bei mir per IP-Adresse eingebunden werden. Dazu auf Einstellung/Integration und dann +Integration hinzufügen klicken und ESPhome auswählen. Danach lohnt es sich, zu schauen, ob alles ankommt. Unter Einstellungen/Integrationen/ESPHome den Knoten auswählen und auf das Gerät klicken.

Es kommt hin und wieder vor, dass bei Umzug auf neue Hardware oder anderen Problemchen mehr als ein Gerät unter einem Namen angezeigt wird. Das führt zu Mehrdeutigkeiten, die Home Assistant dadurch umgeht, indem die Sonsorwerte eine _2 angehängt bekommen.

Mehrdeutigkeiten sind immer schlecht. Die Abhilfe ist, den Knoten aus der Integration komplett zu löschen und erneut hinzuzufügen. Dabei geht in der Regel nichts kaputt, die Sensoren usw. werden wieder mit dem richtigen Namen eingebunden und alles funktioniert normal.

Diagnose: Alles gut, der Knoten läuft!

Jetzt endlich, Butter bei die Fische. Einbinden der relevanten Eigenschaften:

  • Relais
  • Feuchtesensor
  • Klimaregler

ESPHome sammelt Schaltelemente unter switch. Da der Schalter (bzw. das Relais) direkt von einem Pin des Prozessors angesteuert wird, nennt er sich gpio-Switch.

# Relais zu Schalten der Heizung
switch:
  - platform: gpio
    name: "Bad Schalter Infrarotheizung"
    id: switch_infrared
    pin:
      number: D7
      mode: OUTPUT
      inverted: True
    icon: "mdi:heat-wave"   
    restore_mode: ALWAYS_OFF

Ein paar Erklärungen zum Code:

Auf meiner Platine wird der PIN D7 genutzt. Der Key id ist notwendig, um später in ESPHome das Relais steuern zu können.

Ist das Relais korrekt angeschlossen, kann endlich damit gespielt werden. Manche Relais werden allerdings invertiert angesteuert. Kein Problem, einfach die Konfiguration anpassen (inverted: True). In diesem Fall möchte ich auch immer, dass nach einem möglichen Reset das Relais aus ist (restore_mode: ALWAYS_OFF).

Ein Symbol aus der material-design-Sprache kann auch gleich vergeben werden (icon: "mdi:heat-wave"), das sieht hĂĽbsch aus (siehe Bild).

Bei Änderungen der Konfiguration kann man jetzt übrigens immer über WLAN flashen.

Als nächstes der Sensor. Der wird mit I2C ausgelesen, daher muss erst ein I2C-Bus dem ESPhome bekannt gemacht werden:

i2c:
  sda: D2
  scl: D1
  scan: true

Es lohnt sich, zwischendurch erneut zu flashen und den Output des Loggings anzuschauen:

Das ESPHome-Logging findet den den Sensor an Adresse 0x76.

Wenn der Sensor korrekt angeschlossen wurde, wird er nach dem Scan erkannt.

Falls nicht: Beliebte Fehler sind, den Pullup (ca. 4,7k Ohm) an der Takt- und Datenleitung zu vergessen. Oder Takt- und Datenleitung zu vertauschen.

Jetzt kann auch der Sensor eingebunden werden. Da in YAML der Key sensor nur einmal vor kommen darf, muss der folgende Eintrag vor oder nach dem WLAN-Sensor eingefĂĽgt werden:

  - platform: bme280
    address: 0x76
    
    update_interval: 1990ms  
    
    temperature:
      name: "Bad Temperatur"
      id: "bad_temp"
      filters:
        - or: 
          - delta: 0.2
          - throttle: 120sec
        
    pressure:
      name: "Bad Druck"
      id: "bad_press"
      accuracy_decimals: 3
      filters:
        - or: 
          - delta: 1
          - throttle: 120sec
        - sliding_window_moving_average:
            window_size: 8
            send_every: 4
            
    humidity:
      name: "Bad Feuchtigkeit"
      id: "bad_humid"
      filters:
        - or: 
          - delta: 1
          - throttle: 120sec

Der Sensor wird mit ca. zwei Sekunden Abstand relativ häufig ausgelesen, damit die Heizung auch schnell anspringen kann. Gleichzeitig wird, wie beim WLAN-Sensor, die Übetragungshäufigkeit durch die Filter begrenzt. So kommen starke Änderungen schnell an, ohne durch ständige Updates die Datenbank in Home Assistant zu verstopfen.

Jetzt steht die Temperaturregelung auf der Agenda und die beschreibe ich im Heft, unter genau dieser ZwischenĂĽberschrift: "Die Temperaturregelung".

Um zu erkennen, ob die Feuchtigkeit im Raum ansteigt, hilft es als erstes, sich in Home Assistant deren Verlauf grafisch anzeigen zu lassen. Praktischerweise ist die jetzt benötigte Funktion schon eingebaut, sie heißt sensor statistics. Zumindest zum Zeitpunkt, als ich diesen Artikel schrieb, konnte man die Anzeige noch nicht mittels grafischer Oberfläche zusammenklicken, dazu muss die configuration.YAML in Home Assistant anpassen. Insofern finden die folgenden Konfigurationen direkt dort in Home Assistant statt, nicht in ESPHome!

Auch hier darf natĂĽrlich der Key sensor: nicht mehrfach vorkommen. Wer den schon hat, fĂĽgt darunter folgende Zeilen ein:

  - platform: statistics
    name: "Bad Feuchtigkeit Aenderung 5 Min"
    entity_id: sensor.bad_feuchtigkeit
    state_characteristic: change
    max_age:
      minutes: 5
    sampling_size: 50
    precision: 1

Die platform: statistics ist in der Lage, in der Datenbank alte Sensorwerte in eine Berechnung einzubeziehen. Hier wird die Änderung change in einem Zeitraum von 5 Minuten beurteilt . Der Sensor ist der Name der Entitity/Einheit, wie er in der Integration bad-infrarotheizung zu finden ist.

Wer sicher sein kann, dass niemand beim Duschen stört, kann damit zufrieden sein. Wenn aber zwischendrin jemand reinkommt und die Feuchtigkeit danach nicht mehr ansteigt, muss doch wieder frieren.

Automatisierungen richtig zu programmieren ist oft kniffliger als es erst scheint. Zu vielfältig sind die Möglichkeiten, zu erratisch das Verhalten der Mitbewohner, die sich auch nicht immer an die Automatisierung anpassen möchten.

Letzter Ausweg, keine Ereignisse mehr zu verpassen, ist, sie in einen Status zu zwängen: Der Status ist da immer Status A UND Status B liefert immer ein Ergebnis.

Ich habe daher den Status feuchter als im Durchschnitt hinzugefĂĽgt:

- platform: statistics
    name: "Bad Feuchtigkeit mittel 6h"
    entity_id: sensor.bad_feuchtigkeit
    state_characteristic: mean
    max_age:
      hours: 6

Das erzeugt den Mittelwert der Vergangenheit.

Das template (kein Sensor!) erzeugt den Status:

template:
 - binary_sensor:   
      - name: "Bad feuchter als gerade"
        state: |-
           {{ float(states('sensor.bad_feuchtigkeit'), 50) - 7  
           >  float(states('sensor.bad_feuchtigkeit_mittel_6h'), 50)}}
        unique_id: uuidfuerdensensorbadistsehrfeucht

Der Wert der aktuellen Feuchte wird in float konvertiert, da es sonst als string interpretiert wird. Ein Ersatzwert (50) wird genommen, wenn bei der Konvertierung etwas nicht klappt, der Knoten z.B. offline ist. So vermeidet man Fehlereinträge im Logfile.

Der Vergleich der Feuchte -7 mit dem Durchschnitt aktiviert den Zustand immer, wenn es im Bad 7% feuchter ist als in den letzten sechs Stunden. Sechsstundenduscher haben beim Ă–ffnen der TĂĽre dann Pech, aber das geht in Ordnung.

Der Energiesparminister verweigert die Heizung, wenn es drauĂźen schon recht warm ist ...

Eigentlich kann das jetzt nicht mehr passieren. Wenn doch, liefert Home Assistant sehr gute Möglichkeiten zum Debuggen, unter Trace. Man bekommt dort genau angezeigt, welche Abzweigungen die Automatisierung genommen hat und auch warum. Der Zustand der Werte und Bedingungen lässt sich einblenden. Das alleine spart unglaublich viel Zeit bei der Fehlersuche.

(pek)