Smart Home lokal · Teil 3 von 8
Zwei Ventile, zwei Welten: AVM und Sonoff im selben Haus
Beide Ventiltypen messen am heißen Heizkörper. Dem Sonoff kann man einen Raumfühler geben, dem AVM nur einen verschobenen Sollwert, und einen Handgriff dürfen beide nicht überfahren.
Gästezimmer, 20.09., drei Fühler in derselben Minute:
Ventilkopf am Heizkörper 22,0 °C
Raumfühler an der Wand 19,4 °C
Ecke 17,5 °C
Das Ventil regelt nach dem obersten Wert. Bei Sollwert 20 schließt es also, wenn der Raum bei 17,4 steht. Am Vortag lief dort ein zwölfstündiges Komfortfenster mit Sollwert 20, der Raum blieb bei 18,7. Home Assistant hatte den richtigen Zielwert geschickt, aber wie weit das Ventil öffnet, entschied es allein. Wir hatten zuerst sein Regelverhalten im Verdacht, die drei Zahlen erklären es einfacher.
Bei uns hängen zwei Ventilfamilien. Vier Ventile laufen über die FRITZ!Box per DECT (Büro, Schlafzimmer, zwei im Essbereich): ein AVM FRITZ!Smart Thermo 301 und drei Comet DECT von Eurotronic. Über die FRITZ!Box verhalten sie sich gleich, wir nennen sie der Einfachheit halber AVM-Ventile. Dazu kommen zwei Sonoff TRVZB über Zigbee2MQTT (Wohnzimmer, Gästezimmer). Alle haben dieses Problem. Nur eine Familie lässt es sich abgewöhnen.
AVM: Der Sollwert wird zur Stellgröße
Ein FRITZ!DECT-Ventil kennt keinen externen Fühler, es regelt immer nach seinem Kopf. Also verschieben wir den Sollwert um den Fehler, den der Kopf gerade macht:
ausgleich = Kopf − Raum, gedeckelt auf ±3 K
soll = Ziel + ausgleich, gedeckelt auf 8 bis 28, auf 0,5 gerundet
Erste Probe im Schlafzimmer am 20.09.: Ziel 20,5, Kopf 20,5, Raum 19,0, geschrieben 22,0. Das Ventil heizt, bis der Raum das Ziel hat, nicht bis sein Kopf es zeigt.
Die FRITZ!Box kennt dafür den Temperatur-Versatz. Der ist aber fest, und der Fehler ist es nicht. Gemessen am Gästezimmerventil, als es noch nach dem eigenen Kopf regelte (19.09.):
| Zeit | Kopf | Raum | Abstand |
|---|---|---|---|
| 22:06 | 18,4 | 17,8 | +0,6 K |
| 22:26 | 19,0 | 17,8 | +1,2 K |
| 22:46 | 20,0 | 17,8 | +2,2 K |
| 23:16 | 21,0 | 18,7 | +2,3 K |
Wer nur am Schaltpunkt rechnet, solange der Heizkörper kalt ist, erfasst ein Viertel des Fehlers, und das Ventil macht rund anderthalb Grad zu früh zu. Man muss laufend nachregeln. Versatz und Ausgleich zugleich zu setzen hieße, doppelt zu korrigieren.
Die Hausregel: Ein Handgriff hält bis zum nächsten Schaltpunkt
Anfangs zog eine Automation alle fünf Minuten auf den Zielwert zurück, ein Dreh am Ventil hielt keine Viertelstunde. Seit dem 09.09. arbeitet die Steuerung wie ein klassisches Thermostat: Home Assistant schreibt nur am Schaltpunkt, also wenn sich sensor.<raum>_zieltemperatur ändert, etwa weil Vorheizen beginnt oder ein Komfortfenster endet. Dazwischen gilt, was jemand eingestellt hat, am Ventil, in der FRITZ!App oder per Alexa. Angefasst wird nur der Raum, dessen Zielwert sich geändert hat.
Laufendes Nachregeln verträgt sich damit nicht. Wer alle 15 Minuten schreibt, überfährt jeden Handgriff.
Der Merker
Die Lösung kam von uns, nicht von Claude: Nachregeln ist erlaubt, solange am Ventil noch genau der Wert steht, den die Steuerung zuletzt selbst geschrieben hat. Diesen Wert hält je Ventil ein Helfer, input_number.<raum>_zuletzt_geschrieben.
Ventilsollwert == Merker -> niemand hat gedreht, nachregeln erlaubt
Ventilsollwert != Merker -> Handgriff, Finger weg bis zum nächsten Schaltpunkt
Drei Details machen das tragfähig:
- Der Merker speichert, was wirklich am Ventil steht, nicht was wir wollten. Am Schaltpunkt wird geschrieben, nach zwei Minuten einmal nachgefasst, 20 Sekunden später wandert der tatsächliche Sollwert in den Merker. Geht ein Funkbefehl verloren, versucht es der nächste Durchlauf erneut. Speicherte der Merker den Wunschwert, hielte die Steuerung ihren eigenen Fehlschlag für einen Handgriff.
- Das eigene Echo. Das AVM-Ventil rastet in halben Graden und meldet seinen Sollwert gerundet zurück. Deshalb wird vorher auf 0,5 gerundet und mit Toleranz 0,25 verglichen.
- Geschrieben wird nur ab 0,5 K Unterschied. Jeder Befehl kostet Batterie und eine Ventilbewegung.
Der Kern von zimmer_ventile_nachregeln, die Büro und Schlafzimmer alle 15 Minuten bedient:
- if:
- condition: template # ... (Prüfung auf unavailable gekürzt)
value_template: >-
{{ kopf is not none
and (steht | float(-99) - (gemerkt | float(-99))) | abs < 0.25 }}
then:
- variables:
neu: >-
{% set r = raumwert | float %}
{% set z = zielwert | float %}
{% set a = [[(kopf | float) - r, 3.0] | min, -3.0] | max %}
{% set mit = ((([[z + a, 28.0] | min, 8.0] | max) * 2) | round(0) / 2) %}
{% set rein = ((([[z, 28.0] | min, 8.0] | max) * 2) | round(0) / 2) %}
{% set voll = 28.0 %}
{{ rein if r >= z
else (voll if r < z - 0.5
else (mit if (gemerkt | float) >= voll - 0.01 else gemerkt)) }}
- if:
- condition: template # nur ab einem halben Grad
value_template: "{{ (neu | float - (gemerkt | float(-99))) | abs >= 0.5 }}"
then:
- action: climate.set_temperature # ...
- delay: "00:00:30"
- action: input_number.set_value # ... Merker <- state_attr(ventil, 'temperature')
Geprüft am 20.09.: Raum 18,5, Kopf 20,5, Ziel 20,0 ergab 22,0, der Merker zog nach. Von Hand auf 24,0 gedreht: kein Schreibvorgang. Der nächste echte Schaltpunkt setzte 19,5 samt Merker. Im Alltag erkannte die Steuerung am 23.09. einen Sollwert von 25,5 am Schlafzimmerventil als Handgriff, der Merker stand bei 23,0. Sie ließ ihn bis zum nächsten Schaltpunkt stehen.
Ein Fallstrick liegt im Helfer: input_number.set_value verwirft Werte außerhalb von min/max still. Ein Merker mit zu niedriger Obergrenze nähme den Sollwert nicht an, und die Steuerung hielte ihren eigenen Befehl für einen Handgriff. Vor der Umstellung auf 28 (siehe unten) haben wir deshalb geprüft: Die Merker reichen bis 28.
Drei Fälle statt einer Wache
Zuerst gab es eine Wache, Raum >= Ziel + 0,5 -> nicht anfassen, um Batterie zu sparen. Sie blockierte auch das Zurücknehmen: Ein beim Aufheizen auf Ziel + 3 geschobener Sollwert kam nicht mehr herunter. Claudes Begründung, das laufe sich nicht hoch, stimmte nur für den Endpunkt (das Ventil regelt auf Kopf = Soll, eingesetzt bleibt Raum = Ziel), nicht für den Weg dorthin. Dazu rechnete der Schaltpunkt mit heißem Kopf: Am 23.09. um 16:00 fiel das Ziel im Schlafzimmer auf 16, der Kopf stand bei 25,5, geschrieben wurde 19,0.
Seit dem 24.09. gilt:
Raum unter Ziel − 0,5 -> Ziel + (Kopf − Raum), gedeckelt auf 3
Raum am oder über Ziel -> reiner Zielwert, das Ventil schließt
dazwischen -> bleibt, wie es ist (Totzone gegen Takten)
Geprüft mit Ziel 16: Raum 15,0 ergab 19,0, bei 15,7 blieb es ohne Schreibvorgang bei 19,0, bei 16,2 kam 16,0. Genau das hatte die alte Wache verhindert. Liegt ein Schaltpunkt daneben, holt ihn das Nachregeln jetzt binnen 15 Minuten zurück.
Am 25.09. änderte sich der erste Fall (Diagnose in Teil 2). Beim Aufheizen erreichte der Kopf 25 bei Sollwert 26, das Ventil hielt sich für fast fertig, der Raum stieg nur noch 0,7 statt 1,6 K pro Stunde. Seitdem heißt „unter Ziel − 0,5“ in Büro und Schlafzimmer: 28, der höchste Sollwert, ganz offen. Den Ausgleich rechnet das Nachregeln erst im letzten halben Grad, wenn es von 28 kommt. Boost kam nicht in Frage: Er öffnet zwar, setzt temperature in Home Assistant aber auf leer, und damit kämen weder der Merker noch die Anbindung über Matter an Alexa zurecht. Der Preis: Hängt ein Raumfühler auf einem zu tiefen Wert fest, bleibt das Ventil auf 28, bis Zigbee2MQTT ihn nach 25 Stunden als nicht verfügbar meldet.
Essbereich: zwei Ventile, ein Fühler
Im Essbereich hängt ein AVM-Ventil frei an der Wand, das andere hinter einem Schrank in gestauter Luft. Das Schrankventil meldet zu warm und schließt zu früh. Bis zum 20.09. war das Wandventil der Maßstab, seitdem rechnet ein Raumfühler beide:
Wand <- Ziel + (Wand − Raumfühler)
Schrank <- Ziel + (Schrank − Raumfühler)
Fällt der Raumfühler aus, gilt wieder der alte Weg: Wandventil als Maßstab, Aufschlag für den Schrank. Nachgeregelt wird mit zwei Merkern. In der Probe stand das Schrankventil von Hand auf 25, bei Raum 19,0 und Ziel 21,0. Das Wandventil wurde auf 22,0 nachgeregelt, das Schrankventil blieb unberührt. Erster Lauf im Alltag am 21.09.: Ziel 23,0, Raum 21,1, Wandventil (Kopf 20,5) bekam 22,5, Schrankventil (Kopf 21,5) 23,5.
Die 28 beim Aufheizen hat der Essbereich nicht bekommen. Zeigt er dasselbe Drosseln wie das Schlafzimmer, ist es dieselbe Änderung.
Was nur in der FRITZ!Box geht
Die AHA-Schnittstelle kennt für Heizkörperregler nur sethkrtsoll, sethkrboost und sethkrwindowopen. Eco, Komfort, Zeitpläne, Gruppen und Versatz gibt es nur in der Weboberfläche, die AVM-Integration zeigt Eco und Komfort lediglich an. Unser Box-Benutzer für Home Assistant hat bewusst nur Smart-Home-Rechte. Für die Heizung stört das nicht, Home Assistant stellt absolute Sollwerte.
Einmal haben wir es mit erweiterten Rechten über das Formular der Weboberfläche versucht. Das ist keine Schnittstelle: Speichern heißt, alle 54 Felder zurückzusenden. Die Temperaturen kamen an, der Wochenplan war weg und ließ sich nicht wiederherstellen. Nach dem ersten Gerät haben wir abgebrochen.
Der Boxplan als Rückfall, und warum er weg ist
Am 31.08. wollten wir alle Zeitpläne in der Box löschen. Claude widersprach: Ein FRITZ!DECT-Ventil hält ohne neue Anweisung seinen letzten Sollwert. Fällt der Server im Winter nachts während der Absenkung aus, bleibt das Haus bei 16 °C. Also blieben die Pläne als Rückfall, und Home Assistant zog nach. Per AHA an Home Assistant vorbei auf 17,0 gestellt, stand nach spätestens 30 Sekunden wieder 23,0. Der Preis: 14:24:49 Soll 17,0 vom Boxplan, 14:24:53 Soll 23,0 von der Automation, zwei Motorfahrten täglich für nichts.
Nach dem verlorenen Wochenplan setzten wir am 02.09. alle vier AVM-Ventile auf Werkseinstellung, ohne Zeitplan und Versatz. Seitdem ist Home Assistant ihre einzige Steuerung. Fällt der Server aus, halten sie ihren letzten Sollwert, den Frostschutz behält das Gerät. Das nehmen wir bewusst in Kauf: Die meiste Zeit stehen die Ventile auf dem Absenkwert, ein Ausfall fröre sie also mit hoher Wahrscheinlichkeit bei 16 °C ein. Dafür arbeitet nichts mehr gegeneinander. Beim Schreiben dieser Serie noch einmal nachgesehen: Keins der vier Ventile meldet eine nächste geplante Schaltung. Ein späterer Eintrag in unserer eigenen Doku, der wieder von einem Boxplan sprach, war falsch und ist berichtigt.
Sonoff TRVZB: Der Raumwert geht ins Ventil
Das TRVZB kann nach einem externen Fühler regeln, holt sich den Wert aber nicht selbst:
select.heizung_gastezimmer_temperature_sensor_select -> external
number.heizung_gastezimmer_external_temperature_input <- sensor.klima_gastezimmer_temperature
Die Automation gastezimmer_ventil_raumfuehler schreibt bei jeder Meldung des Raumfühlers, alle zehn Minuten und beim Start, aber nur, wenn es etwas zu schreiben gibt:
# ... (vorher: Auswahl auf external, falls nötig)
- condition: template # ab 0,1 K Änderung oder nach 25 Minuten
value_template: >-
{% set n = states.number.heizung_gastezimmer_external_temperature_input %}
{% set alt = n.state | float(-99) %}
{% set neu = states('sensor.klima_gastezimmer_temperature') | float(-99) %}
{{ (neu - alt) | abs >= 0.1
or (now() - n.last_updated).total_seconds() > 1500 }}
- action: number.set_value
target:
entity_id: number.heizung_gastezimmer_external_temperature_input
data:
value: "{{ states('sensor.klima_gastezimmer_temperature') | float }}"
Schweigt der Raumfühler eine halbe Stunde, schaltet die Automation das Ventil auf internal zurück und meldet es. Ein Ventil, das auf einen eingefrorenen Wert regelt, heizt im schlimmsten Fall endlos. Geprüft am 20.09.: Nach dem Umschalten meldete das Ventil als Ist-Temperatur 19,4 statt 21,9, den Raumwert. Mit dem Fühler testweise auf unavailable fiel es auf internal zurück, die Meldung erschien. Das Wohnzimmer bekam am selben Tag einen Fühler und eine Kopie der Automation.
Einen Ausgleich rechnen wir hier nicht. Das Ventil regelt schon nach dem Raumwert, ein Aufschlag auf den Sollwert korrigierte denselben Fehler ein zweites Mal. Am Schaltpunkt bekommen beide TRVZB den reinen Zielwert. Einen Merker brauchen sie nicht: Zwischen den Schaltpunkten schreibt Home Assistant ihnen keinen Sollwert.
Der Raumwert ist nur so gut wie der Fühler. Der im Gästezimmer meldete erst ab 1,0 K Änderung, das Ventil bekam den Raumwert vom 20. bis 21.09. also in ganzen Grad. Mehr zu Meldeschwellen in Teil 5.
Der Modus-Fallstrick
Bei der ersten Bestandsaufnahme fanden wir im Wohnzimmerventil einen durchdachten Wochenplan, der nicht lief. Das Ventil stand in heat, fest auf 19 °C. Den Geräteplan befolgt ein TRVZB nur in auto.
Am 31.08. kam die Umkehrung dazu. Ein geschriebener Sollwert wirft das Ventil aus auto nach heat, aber nur, wenn sich der Wert ändert. Unsere erste Messung lief von 16 auf 22 und verdeckte das. Im Gästezimmer stand der Sollwert schon auf 16,0, die Automation schrieb 16,0, und das Ventil blieb in auto. Die Ablaufspur sah richtig aus, set_temperature war nachweislich aufgerufen worden.
Seitdem setzt heizung_raeume_regeln den Modus ausdrücklich auf heat, wenn das Ventil nicht dort steht, wartet drei Sekunden und schreibt erst dann den Sollwert. Seit dem 09.09. stehen beide TRVZB dauerhaft in heat. Nach dem Firmwaresprung des Wohnzimmerventils von 1.3.0 auf 1.4.4 am 13.09. haben wir nachgeprüft: auto springt auf den Wochenplan, heat zurück auf den letzten Handwert, wie vorher.
Der Schaltabstand ab Werk
27.09., Sonntag 17:00: Gästezimmer 20,9 °C bei Ziel 22.
| Zeit | Ventil | Raum |
|---|---|---|
| 06:06–09:20 | heizt | 20,2 → 22,0 |
| 09:20–11:43 | ruht | 22,0 → 21,0 |
| 11:43–17:00 | heizt | 20,8–21,3 |
Die Pause am Vormittag war Werkseinstellung. temperature_accuracy ist in Zigbee2MQTT der Schaltabstand des TRVZB und stand auf −1,0: Ist das Ziel erreicht, schließt das Ventil und öffnet erst ein ganzes Grad darunter. Um 11:43:08 öffnete es bei genau 21,0. Ein Raum, der ein Grad unter dem Ziel ruht, sieht aus wie eine zu schwache Heizung.
Möglich sind −1,0 bis −0,2 in Schritten von 0,2. Wir haben −0,4 gesetzt, per number.set_value, und danach das Gerät selbst über zigbee2mqtt/Heizung Gästezimmer/get gefragt: −0,4. Es öffnet jetzt bei 21,6. Kleinere Werte hießen häufigeres Takten des Motors. Das Wohnzimmerventil steht noch auf −1,0.
Den Nachmittag erklärt das nicht. Die Therme lieferte sehr wahrscheinlich kein warmes Wasser mehr. Den Beleg lieferte ein AVM-Kopf: Das Schlafzimmerventil stand auf 28, sein Kopf fiel trotzdem von 25,5 um 10:00 auf 22,5 um 13:00, während es draußen wärmer wurde. Das passt zur Sommer-Winter-Umschaltung der Therme nach Außentemperatur.
Im Vergleich
| FRITZ!DECT (AVM, Comet) | Sonoff TRVZB | |
|---|---|---|
| Externer Fühler | nicht möglich | temperature_sensor_select: external, Wert per Automation |
| Steuerung | Sollwert verschoben, alle 15 min nachgeregelt, beim Aufheizen 28 (Essbereich noch nicht) | reiner Zielwert am Schaltpunkt, Raumwert laufend eingespeist |
| Handgriff-Erkennung | Merker je Ventil | nicht nötig, zwischen Schaltpunkten wird nichts geschrieben |
| Fallstricke | Boost leert den Sollwert; Eco, Komfort, Versatz nur in der Weboberfläche; Echo in halben Graden | auto → heat nur bei Wertänderung; Schaltabstand −1,0 ab Werk; Meldeschwelle des Fühlers |
| Kopf als Heizkörperanzeiger | ja | nein, meldet den Raumwert |
| Server aus | hält den letzten Sollwert | hält den letzten Sollwert in heat, der Geräteplan schläft |
Was wir mitnehmen
- Beide Ventiltypen messen am Heizkörper. Im Gästezimmer lagen Kopf und Wand 2,6 K auseinander.
- Kann das Ventil einen externen Fühler, dort einspeisen und nichts zusätzlich rechnen. Kann es das nicht, den Sollwert verschieben, laufend und nicht nur am Schaltpunkt.
- Nachregeln und Handgriffe vertragen sich, wenn ein Merker festhält, was nach allen Versuchen wirklich am Ventil steht. Nie den Wunschwert merken.
- Beim TRVZB den Modus ausdrücklich setzen. Ein Sollwert kippt ihn nur, wenn er sich ändert.
- Wirkt ein TRVZB-Raum kühl, zuerst
temperature_accuracyansehen und nach dem Setzen vom Gerät zurücklesen. - Vor dem Schreiben in einen Helfer seine Grenzen prüfen:
input_numberverwirft Werte außerhalb von min/max still.