Ein Thermostat im ESPHome
über
Vor etwa einem Jahr beschloss ich, mich an der Automatisierung meines Heims zu versuchen. Mein erster Meilenstein war die Automatisierung des Thermostats in unserem Wohnzimmer. Dazu ersetzte ich den vorhandenen Wandthermostat durch den WLAN-Thermostat (Elektor-Projekt 160269, veröffentlicht in der Februarausgabe 2018 [1][2]), den ich mit ESPHome-basierter Firmware umprogrammiert hatte. Die neue Firmware „virtualisierte“ alle Bedienelemente der Desktopvariante (in Worten: ein Relais, zwei Drucktasten und drei LEDs), so dass sie von einer Hausautomatisierungssteuerung wie dem Home Assistant bedient werden konnte.
In diesem System spielt der Home Assistant auf einem Raspberry Pi die Rolle des Thermostaten, das heißt, er entscheidet, wann die Heizung ein- oder ausgeschaltet wird. Der Tischthermostat selbst ist zu einem einfachen ferngesteuerten Relais mit einigen LEDs degradiert worden.
Ganz nett, aber...
Das System funktionierte gut und half uns bequem durch den Winter 2019/20, doch brachte die Wintersonne einige Unzulänglichkeiten an den Tag:
1. WLAN-Netzwerk erforderlich
2. Home Assistant erforderlich
3. unästhetisch!
Zukunftssicher? Aber sicher!
Als ich den Thermostat testete, war das erste Problem kein großes Problem, da die meisten von uns ein WLAN im Haus haben. Wenn es nicht mehr funktioniert, wird es einfach durch einen Neustart des Routers (oder was auch immer) wieder in Gang gesetzt. Doch wie vieles im Leben kommen und gehen Technologien, und es gibt keine Garantie, dass es immer ein WLAN geben wird. Unsere Wohnungen werden aber auch in dreißig oder mehr Jahren noch da sein. Mit anderen Worten, ein einigermaßen zukunftssicheres Design wäre wünschenswert.
Rückwärtsgewandt? Auch das!
Der zweite Punkt hängt mit dem ersten zusammen, da auch Home Assistant und Raspberry Pi eines Tages verschwinden könnten. Aber es ist noch schlimmer: Ich weiß immer, wie mit dem Home Assistant auf dem Raspberry Pi umzugehen ist, aber die meisten Leute, die ich kenne, haben keine Ahnung davon. Damit auch andere Leute meinen automatischen Thermostat benutzen können, muss er auch „past-proof“ sein. Er sollte wie ein klassischer Wandthermostat aussehen und sich auch wie einer verhalten. Die Automatisierung darf nicht aufgezwungen werden, sondern es sollte eine optionale Funktion bleiben. Die Automatisierung ist für diejenigen, die sie benutzen wollen, aber wer das nicht will, soll nicht davon gehindert werden.
Reine Geschmackssache
Die dritte Frage ist etwas subjektiv. Der automatische Tischthermostat baumelte am Ende eines Drahtstücks, das mit einem Loch in der Wand verbunden war, wo sich der alte Thermostat befand (Bild 1).
Ein paar unbenutzte Netzkabel, die aus der Wand ragten, wurden mit Isolierbandstücken vor neugierigen Fingern geschützt. Da der Tischthermostat eine 5-V-Stromversorgung über einen USB-Anschluss benötigt, wurde er von einem Telefonladegerät versorgt, das an einer nahe gelegenen Steckdose angeschlossen war. Es gab also mehrere äußerst sichtbare Drähte, während der ursprüngliche Thermostat keine hatte. Obwohl es ein ausgezeichneter Aufhänger für einen Smalltalk war, fanden die meisten Besucher das System nicht unbedingt schön (sondern stattdessen „hässlich“, „seltsam“ und „gefährlich“, Banausen halt).
Zurück zum Zeichenbrett
Die Unzulänglichkeiten (und der Spott meiner Freunde) führten zu der Entscheidung, den ursprünglichen Tischthermostat umzugestalten. Dies führte zu folgendem „Pflichtenheft“:
1. Lokale Einstellung der Soll-Temperatur am Gerät.
2. Lokale Steuerung setzt die Automatisierung außer Kraft.
3. Netzspannungsbetrieb
4. Saubere Anschlüsse und ein professionell wirkendes Gehäuse.
Der zweite Punkt betrifft die Software, die drei anderen haben (nur) etwas mit der Elektronik des neuen Thermostats zu tun.
Pflicht Nr. 1 bedeutet eine intuitive Benutzerschnittstelle zur Einstellung der Soll-Temperatur. Der Tischthermostat verfügt zwar über zwei Drucktasten zur Auf- und Abwärtsregelung der Zieltemperatur, es gibt aber kein Display, das diese Temperatur anzeigen könnte. Da es (nicht unmöglich, aber) recht kompliziert ist, die I/O-Pins für das Display bei einem kleinen WLAN-Modul zur Verfügung zu stellen, scheint ein einfaches Potentiometer mit einer kalibrierten Skala der bessere Weg. Und einen bisher ungenutzten analogen Eingang besitzt das WLAN-Modul dann auch!
Auch die dritte Anforderung will wohlüberlegt sein. Für eine WLAN-Verbindung und zur Versorgung des Relais wird etwa 1 W Leistung benötigt. Der Bau einer kleinen Stromversorgung mit Transformator ist zwar möglich, aber es ist schwierig, sie klein genug zu halten, denn schließlich wollen wir keine riesige Kiste an der Wand. Der ursprüngliche Thermostat besaß ein transformatorloses Netzteil, das für relativ konstante Lasten gut funktioniert, aber bei den variablen Lastströmen einer WLAN-Verbindung vielleicht oder eher wohl nicht. Meine Absicht war es deshalb, ein kleines AC/DC-Wandlermodul zu verwenden.
Nun noch ein geeignetes Gehäuse. In den entsprechenden Katalogen konnte ich nichts Passendes finden, und auch, wenn im Zeitalter von FabLabs, 3D-Druck und Laserschneiden die Produktion eines (!) kundenspezifisches Gehäuses kein unüberwindbares Hindernis darstellt, habe ich es mir noch einfacher gemacht und mich entschlossen, das ursprüngliche Thermostatgehäuse weiterhin verwenden, da es bereits alles enthielt, was ich brauchte: ein Potentiometer mit einer Skala, eine LED und einen Netzschalter. Außerdem besaß es an den richtigen Stellen Befestigungslöcher (ich brauchte keine neuen Löcher in die Wand bohren) und stellte eine gute Möglichkeit dar, eine Platine durch den Gehäuseboden hindurch an die Netzspannung anzuschließen.
Meine Modifikationen liefen also darauf hinaus, den neu gestalteten Desktop-Thermostat so auf eine Platine zu packen, dass alles in das bestehende Gehäuse passte, wobei das Potentiometer, die LED, der Netzschalter und der Netzstecker in genau den gleichen Positionen wie beim ursprünglichen Gerät angeordnet sein mussten.
Die Änderungen der Schaltung des Tischthermostats war einfach genug (Bild 2).
Ich ersetzte die USB-Stromversorgung durch ein 5-V-AC/DC-Modul und fügte ein Potentiometer hinzu. Ein Widerstand zur Spannungsbegrenzung war ebenfalls nötig, da das WLAN-Modul keine Spannungen über 1,1 V verarbeiten kann. Die beiden Drucktasten und die drei LEDs blieben erhalten, da sie sich irgendwann als nützlich erweisen könnten.
Es war ein glücklicher Zufall, dass das AC/DC-Modul gerade so klein war, dass es unter den großen Plastikknopf des Potis passte. Poti, Netzschalter und Klemmenleiste wurden aus dem alten Thermostat recycelt (Bild 3).
Ich musste das alte 48-V-Relais durch eine 5-V-Version ersetzen. Das Relais aus dem Tischthermostaten wollte partout nicht passen, aber zum Glück war das Relais des alten Thermostaten Mitglied einer altehrwürdigen Industriestandardfamilie, die immer noch erhältlich ist, auch in einer 5-V-Ausführung.
Alles auf eine Platine auzuordnen, die in das Originalgehäuse passte, erforderte eine Menge Arbeit mit der Schieblehre, aber am Ende gelang es. Alle SMDs einschließlich des WLAN-Moduls wurden auf der Unterseite der Platine untergebracht (Bild 4), während alle bedrahteten Bauteile auf der Oberseite Platz fanden.
Ein wenig zusätzliche Platinenfläche wurde dadurch gewonnen, dass einige ungenutzte Montagelöcher des Gehäuses verdeckt und einige hinderliche Kunststoffteile im Inneren des Gehäuses kurzerhand abgeschnitten wurden. Um alle Leiterbahnen zu routen, war ein „flexibler Ansatz“ der empfohlenen Isolationsvorgaben leider unvermeidlich.
Software
Die ursprüngliche ESPHome-Firmware musste ebenfalls überdacht werden. Anstatt einfach alle Sensoren und Aktuatoren des Thermostaten freizulegen und den Home Assistant den Rest erledigen zu lassen, musste ich nun Automatisierungen innerhalb von ESPHome vornehmen. Die Programmierung und Konfiguration erfolgt in der YAML-Datei des ESPHome-Projekts des Thermostats (siehe Hausautomation leicht gemacht).
Raumtemperatur messen
Für den eingesetzten Raumtemperatursensor DS18B20 (ursprünglich von Dallas, jetzt Maxim und sogar Analog Devices) an GPIO-Pin 5 besitzt ESPHome eine spezielle Dallas-Komponente. Daraus ergibt sich folgender Eintrag:
dallas:
- pin: GPIO5
sensor:
- platform: dallas
address: 0x6D00000C24013928
name: "Measured temperature"
id: t_room
filters:
- offset: 0.0
Die erste Zeile veranlasst ESPHome, sein Dallas-1-Draht-Kommunikationsmodul einzubeziehen, die zweite, es an GPIO5 anzuschließen. Der Sensor ist von der dallas-Plattform, address ist optional. Wenn Sie sie die eindeutige Adresse angeben, muss sie natürlich korrekt sein. Sie können sie im ESPHome-Log nachschlagen (verwenden Sie nicht meine!). Die Angabe der id: t_room ist hier erforderlich, da wir an anderer Stelle der YAML-Datei auf sie verweisen müssen (siehe unten). Mit den filters könnte man die gemessenen Werte in irgendeiner Weise korrigieren.
Soll-Temperatur
Die Soll-Temperatur wird mit dem Potentiometer eingestellt. Dazu wird in den sensor-Bereich der YAML-Datei ein Sensor des Plattform-Typs adc mit einem Spannungswert definiert. Mit den so genannten Sensorfiltern wird die Sensorspannung in den auf das Gehäuse gedruckten Temperaturwert umgerechnet. Die Gleichung Ttarget = 25•Vin + 6.75 passt in meinem Fall recht gut. Daraus ergibt sich ein multiply-Filter mit dem Wert 25 und ein offset-Filter mit dem Wert 6,75. Wenn man die Einheiten in °C angibt, behandelt Home Assistant diese Daten automatisch als Temperatur.
- platform: adc
name: "Target temperature"
id: t_target
icon: "mdi:temperature-celsius"
pin: A0
update_interval: 5s
# Convert potentiometer scale to °C (min=6.75°C, max=31.75°C)
filters:
- multiply: 25.0
- offset: 6.75
unit_of_measurement: "°C"
on_value:
then:
- lambda: |-
auto call = id(t_controller).make_call();
call.set_target_temperature(x);
call.perform();
Der Teil nach on_value: ist eine Automatisierung und wird weiter unten erläutert. Zuerst sehen wir uns das Relais an.
Schalten der Heizung
Dies ist ziemlich einfach, da das Relais nur ein Schalter an GPIO 4 und daher Teil der gpio-Plattform ist. Wie der Temperatursensor benötigt es eine Id (heater), um für andere Teile der YAML-Datei zugänglich zu sein.
switch:
- platform: gpio
pin: GPIO4
name: "Heater"
id: heater
Volle Klimakontrolle
Wir haben bisher einen Sensor für die Raumtemperatur (t_room), ein Poti für die Soll-Temperatur (t_target) und ein Relais, um die Heizung ein- und auszuschalten (heater).
ESPHome verfügt über eine climate-Komponente zur Steuerung von Heiz- und Kühlgeräten. Ein Thermostat ist eine solche Klimakomponente. Dies erspart einiges an Arbeit und stellt zudem ein schönes grafisches Steuerungs-Widget in der Benutzerschnittstelle des Home Assistant zur Verfügung.
climate:
- platform: thermostat
name: "Thermostat"
id: t_controller
sensor: t_room
default_target_temperature_low: 20 °C
heat_action:
- switch.turn_on: heater
idle_action:
- switch.turn_off: heater
hysteresis: 0.5
away_config:
default_target_temperature_low: 15 °C
Der Thermostat kühlt nicht, sondern kann nur heizen, was es zum Mitglied der ESPHome-thermostat-Plattform macht. Es benötigt eine id, damit es innerhalb der YAML-Datei gesteuert werden kann. Ich habe die id auf t_controller gesetzt.
Die Klimakomponente besitzt einen Eingang für den Temperatursensor, den wir mit t_room verbinden. Sie muss auch an eine Heizung angeschlossen werden, was wir dank des Heizungsschalters, den wir zuvor definiert haben, tun können.
Man könnte erwarten, dass auch eine Klimakomponente auch einen Eingang für die Soll-Ttemperatur besitzt. Dies ist aber nicht der Fall. Vielleicht wird dies ja in einer zukünftigen Version von ESPHome hinzugefügt? Stattdessen gibt es eine Steuerung der Soll-Temperatur, ähnlich wie das Poti des Thermostats. Glücklicherweise gibt es einen Weg, diese Beschränkung zu umgehen, und zwar die so genannten Lambda-Blöcke.
Lambda-Blöcke
Das Konzept der Lambda-Blöcke ist großartig und schrecklich zugleich. Es ist großartig, weil man mit ihnen (fast) alles machen kann, was man will, und sie sind schrecklich, weil sie dem ganzen Konzept widersprechen, Geräte mit einer einfachen YAML-Datei zu konfigurieren, ohne dass man C++-Kenntnisse haben müsste.
Einfach ausgedrückt: Ein Lambda-Block ist C++-Code, der in das ESPHome-Projekt eingebaut wird. Um zu einer brauchbaren YAML-zu-C++-Schnittstelle zu gelangen, mussten die Entwickler einiges an Verrenkungen durchführen, mit dem Ergebnis, dass Lambda-Code komplizierter ausfällt, als es bei normalem C++ der Fall gewesen wäre.
Eigentlich sollten Sie darüber nachdenken, statt Lambda-Blöcke eine eigene Komponente zu erstellen. ESPHome unterstützt benutzerdefinierte Komponenten für fast alles. Ich war kurz davor, aber schließlich entschied ich mich, dieses Thema für einen weiteren Artikel aufzusparen.
Die C++-Schnittstelle der Klimakomponente besitzt eine Funktion zur Einstellung der Soll-Temperatur. Der Lambda-Block im on_value-Abschnitt des Potentiometersensors zeigt, wie sie zu verwenden ist. Jedes Mal, wenn ein neuer Wert verfügbar ist, wird die Methode set_target_temperature der Klimakomponente t_controller aufgerufen:
on_value:
then:
- lambda: |-
auto call = id(t_controller).make_call();
call.set_target_temperature(x);
call.perform();
In normalem C/C++ wäre dies in etwa so (einfacher) gewesen:
t_controller.set_target_temperature(x);
Hätte die Klimakomponente einen Eingang für die Soll-Temperatur gehabt, hätten die Dinge schön einfach sein können, wie zum Beispiel:
climate:
- platform: thermostat
name: "Thermostat"
id: t_controller
sensor: t_room
target: t_target
…
Hätte hätte, Sie wissen schon...
Leider ist diese Art der Automatisierung von on_value zu einfach, da sie die Fernsteuerung der Soll-Temperatur vom Home Assistant außer Kraft setzt. Um dies zu lösen, sollte die Automatisierung nur dann laufen dürfen, wenn sich t_target ändert, also jemand am Poti dreht. Da ESPHome keinen on_value_changed-Mechanismus für Sensoren kennt, können wir dies im Lambda-Block erledigen, in etwa so:
on_value:
then:
- lambda: |-
static float x_last = 0.0;
if (x<x_last-0.1 || x>x_last+0.1)
{
x_last = x;
auto call = id(t_controller).make_call();
call.set_target_temperature(x);
call.perform();
}
Die kleine Hysterese x von ±0,1 verhindert zu schnelles Umschalten aufgrund des Sensorrauschens.
Das Delta-Filter
Eine andere und schönere Lösung ist die Verwendung des Delta-Filters auf t_target. Dieses Filter lässt einen neuen Wert nur dann passieren, wenn er sich vom vorherigen Wert um einen Betrag von ±Delta unterscheidet. Wenn also delta = 1 und der letzte Wert gleich 20 war, dann wird der nächste Wert nur dann durchgelassen, wenn er entweder kleiner als 19 oder größer als 21 ist.
- platform: adc
name: "Target temperature"
id: t_target
…
filters:
- multiply: 25.0
- offset: 6.75
- delta: 0.2
…
Die Filter werden in der Reihenfolge ausgeführt, in der sie erscheinen: Das Deltafilter arbeitet mit dem in Grad Celsius umgerechneten Wert und nicht direkt mit der Eingangsspannung. Der Deltawert sollte klein sein, da es sonst schwierig ist, die Thermostatschwelle nur ein wenig nach oben oder unten zu schieben, was den ganzen Unterschied im Benutzerkomfort ausmacht.
Fertigstellung des Geräts
Ist die YAML-Konfigurationsdatei fertig, kann die Firmware auf das WLAN-Modul hochgeladen werden. Bei einem Modul, auf dem noch keine ESPHome-kompatible Software läuft, muss dazu die serielle Schnittstelle verwendet werden (verfügbar auf Header K2), wie es [3] genau beschreibt. Sobald das Modul ESPHome mit aktivierter Over-the-Air-Programmierung (OTA) ausführt (wenn die YAML-Datei die Zeile ota: enthält), kann der Thermostat umprogrammiert werden, ohne physisch mit dem Entwicklungssystem verbunden zu sein.
Der Thermostat sollte so montiert werden, dass der Temperaturfühler nicht durch das WLAN-Modul und die Stromversorgung aufgeheizt wird.
Fazit
Der Artikel zeigt, wie ein vorhandener „dummer“ Thermostat durch einen selbstgebauten, intelligenten und vernetzten Thermostat als Teil der Hausautomatisierung ersetzt werden kann. Es war nicht allzu schwierig, einen Prototyp zu schustern, der in etwa das tut, was er tun soll, und von jedem jederzeit benutzt werden kann. Damit er den ästhetischen Ansprüchen meiner Freund:innen genügt, war etwas mehr Aufwand nötig. Zweifellos wird das neue Thermostat noch etwas Feinabstimmung benötigen, aber da er fernprogrammiert werden kann (in-the-field, wie man sagt), ist dies einfach zu bewerkstelligen.
(200519-03)
Wollen Sie weitere Elektor-Artikel lesen? Jetzt Elektor-Mitglied werden und nichts verpassen!
Diskussion (0 Kommentare)