Die Heizlogik meines KNX-Hauses bestand auf der alten Home-Assistant-Instanz aus 21 Automationen. Auf der neuen sind es 6. Übertragen habe ich sie am 26. September, als Teil des Umzugs von einer Instanz mit 2024.11.1 auf eine neue mit 2026.8, und den Ablauf dabei in meinem Journal mitgeschrieben. Beim Umzug habe ich geändert, was beim Schließen eines Fensters in der Nacht passiert, und am nächsten Morgen zeigten die beiden Instanzen für alle 11 Thermostate unterschiedliche Betriebsarten. Wie die Raumregler angesteuert werden, steht in meinem Post über Preset-Modi von KNX-Thermostaten.
Was umgezogen ist
Die alte Datei enthielt drei Gruppen. 16 Automationen kümmerten sich um offene Fenster in 8 Räumen. 4 schalteten um 21:00 auf Nachtmodus und um 05:00 auf Tagmodus und schrieben den jeweiligen Modus auf 11 Thermostate. 1 Automation setzte den Modus nach einem Start von Home Assistant neu, und sie war seit Januar ausgeschaltet. Auf der neuen Instanz sind aus den 16 eine geworden, die 4 bleiben 4, und die Startup-Automation kam mit, weiterhin ausgeschaltet. Den Nachtmodus-Helfer habe ich zunächst unverändert übernommen und am 9. Oktober initial: off entfernt.
Alle sechs sind auf der neuen Instanz eingerichtet, aber mit initial_state: false deaktiviert. Sie würden die Betriebsart der KNX-Raumregler am Bus schalten, und diese Arbeit macht weiterhin die alte Instanz, unverändert. Ich wollte keine zwei Instanzen, die Betriebsarten auf dieselben Regler schreiben.
Beim Kopieren sind zwei Kleinigkeiten aufgefallen. Eine alte Entity-ID heißt Tagmodus 06:00, während die Automation um 05:00 läuft, und auf der neuen Instanz passt die ID zur Uhrzeit. In der alten Registry hängt außerdem noch ein verwaister Eintrag einer längst gelöschten Temperatur-Snapshot-Automation, angezeigt als unavailable, und den habe ich auf der alten Instanz gelassen.
Aus 16 Kopien wird eine Automation mit Tabelle
Die 16 Fenster-Automationen waren Kopien aus der Oberfläche. Jeder Raum hatte eine namens Deaktivieren (Fenster 5 Sekunden offen, Frostschutz setzen) und eine namens Aktivieren (Fenster 5 Sekunden zu, Komfort setzen). Innerhalb jeder Achtergruppe unterschieden sie sich nur in den Namen von Fenstersensor und Thermostat. Die Idee selbst steht in meinem Post über das Abschalten der Heizung bei offenem Fenster, und sie funktioniert. Bei 16 Kopien muss schon eine Änderung, die nur das Schließen betrifft, 8-mal gemacht werden.
Die neue Fassung ist eine Automation mit zwei Triggern, offen und zu, unterschieden über eine Trigger-ID. Was je Raum verschieden ist, steht in einer Variable, die jedem Fenstersensor seinen Thermostat zuordnet. Die Aktion nimmt den auslösenden Sensor und holt sich aus dieser Tabelle den passenden Thermostat. Raumbezeichnungen und Entity-IDs unten sind Platzhalter.
automation:
- id: heizung_fenster_frostschutz
alias: "Heizung: Fenster offen -> Frostschutz, zu -> geltender Modus"
initial_state: false # Schattenbetrieb während des Umzugs
mode: parallel
variables:
thermostat_je_fenster: &thermostat_je_fenster # eine Zeile pro Raum, 8 in der echten Datei
binary_sensor.fenster_raum_a: climate.thermostat_raum_a
binary_sensor.fenster_raum_b: climate.thermostat_raum_b
binary_sensor.fenster_raum_c: climate.thermostat_raum_c
triggers:
- trigger: state
entity_id: &fenster
- binary_sensor.fenster_raum_a
- binary_sensor.fenster_raum_b
- binary_sensor.fenster_raum_c
from: "off"
to: "on"
for:
seconds: 5
id: offen
- trigger: state
entity_id: *fenster
from: "on"
to: "off"
for:
seconds: 5
id: zu
actions:
- action: climate.set_preset_mode
target:
entity_id: "{{ thermostat_je_fenster[trigger.entity_id] }}"
data:
# VERHALTENSÄNDERUNG: die alte Fassung setzte beim Schließen immer comfort
preset_mode: >-
{% if trigger.id == 'offen' %}building_protection
{% elif is_state('input_boolean.heizung_nachtmodus', 'on') %}economy
{% else %}comfort{% endif %}Die Fensterliste steht nur einmal in der Datei, und der zweite Trigger verwendet sie über einen YAML-Anker wieder, &fenster und *fenster. Für einen neuen Raum ergänze ich je eine Zeile in der Tabelle, in der Fensterliste und in der Liste der Thermostate. Das Preset, das die KNX-Climate-Entität für Frostschutz verwendet, heißt building_protection.
Der nächste Ausschnitt setzt dieselbe Automationsliste fort und zeigt die Nacht-Automation in der Fassung vom 9. Oktober. Sie verwendet die Fenstertabelle über den Anker &thermostat_je_fenster wieder und definiert einen zweiten Anker, &alle_thermostate, für die Liste der 11 Thermostate. Aus beiden berechnet sie die Thermostate, deren Fenster offen ist, und schaltet nur die übrigen. Die Tag-Automation und die Start-Automation verwenden denselben Variablenblock und sind hier nicht gezeigt.
- id: heizung_nachtmodus_anwenden
alias: "Heizung: Nachtmodus auf alle Thermostate anwenden"
initial_state: false
triggers:
- trigger: state
entity_id: input_boolean.heizung_nachtmodus
from: "off"
to: "on"
variables:
thermostat_je_fenster: *thermostat_je_fenster
alle_thermostate: &alle_thermostate # 11 Einträge in der echten Datei
- climate.thermostat_raum_a
- climate.thermostat_raum_b
- climate.thermostat_raum_c
fenster_offen: >-
{% set ns = namespace(l=[]) %}
{% for fenster, thermostat in thermostat_je_fenster.items() %}
{% if is_state(fenster, 'on') %}{% set ns.l = ns.l + [thermostat] %}{% endif %}
{% endfor %}
{{ ns.l }}
ziele: "{{ alle_thermostate | reject('in', fenster_offen) | list }}"
actions:
- if: "{{ ziele | count > 0 }}"
then:
- action: climate.set_preset_mode
data:
preset_mode: economy
target:
entity_id: "{{ ziele }}"Ein Fehler, der jede Nacht passieren konnte
Auf der alten Instanz setzte das Schließen eines Fensters immer Komfort, auch um Mitternacht. Wer nachts ein Zimmer lüftete, stellte es damit zurück auf Komfort, und der nächste zeitgesteuerte Wechsel kam erst um 05:00. Jede der 8 Aktivieren-Kopien hatte dieses Verhalten.
Die neue Automation setzt beim Schließen eines Fensters den Modus, der gerade gilt, nachts Economy und tagsüber Komfort. Sie ist noch ausgeschaltet, wie alles aus diesem Schritt. Das ist der elif-Zweig im Template oben, der den Nachtmodus-Helfer prüft. Es ist eine bewusste Verhaltensänderung, und im Code steht ein Kommentar dazu. Wie oft das passiert ist oder was es an Heizenergie gekostet hat, habe ich nicht gemessen. Als ich die Automationen übertragen habe, schrieb der zeitgesteuerte Wechsel um 21:00 und um 05:00 den neuen Modus auf alle 11 Thermostate, ohne die Fenster zu prüfen. Bei offenem Fenster wurde der Frostschutz in diesem Moment also durch den Tag- oder Nachtmodus ersetzt. Die alte Instanz macht es genauso. Am 9. Oktober habe ich es auf der neuen geändert, das zeigt der Ausschnitt oben. Nacht-, Tag- und Start-Automation überspringen Thermostate mit offenem Fenster jetzt, und die Fenster-Automation setzt den geltenden Modus, wenn der Sensor von on auf off wechselt und fünf Sekunden dort bleibt; kehrt ein Sensor von unknown oder unavailable auf off zurück, löst sie nicht aus. Die Zielliste habe ich über die Template-API mit einem simuliert offenen Fenster geprüft, das ergab 10 von 11 Thermostaten. Ein echter Lauf fehlt noch, weil die Automationen aus sind. Ein Fenstersensor mit unbekanntem Zustand zählt als geschlossen, und drei Thermostate haben gar keinen Fenstersensor.
Fehlende Rückmeldung der Betriebsart nach einem Neustart
Am nächsten Morgen habe ich beide Instanzen verglichen. Die alte zeigte alle Thermostate auf Komfort, die neue zeigte sie auf Standby. Die neue Instanz hatte den Wechsel um 05:00 am Bus korrekt mitgelesen. Nach einem Neustart um 07:19 fragte sie die Betriebsart ab und bekam Standby zurück.
Die Ursache liegt im ETS-Projekt. In meiner Konfiguration fehlt eine lesbare Rückmeldung der aktiven Betriebsart. Home Assistant fragt deshalb das Objekt ab, über das die Betriebsart geschaltet wird, und dieses Objekt liefert nicht die tatsächlich aktive Betriebsart. Die alte Instanz zeigte Komfort nur, weil sie Komfort selbst geschrieben hatte. Nach ihrem eigenen Neustart am Vorabend hatte sie ebenfalls Standby angezeigt, was genauso falsch war.
Zurückmelden tun die Regler die Soll-Temperatur. An diesem Morgen meldeten sie 20,0 °C, das passt zum Komfortwert; 18,0 °C wäre der Nachtwert. Das ist nur ein Hinweis auf die Betriebsart: Ein späterer Test hat gezeigt, dass sich die gemeldete Soll-Temperatur auch mit einer lokalen Verstellung am Regler verschiebt, im getesteten Raum um −1 bis −2 K (Details im Thermostat-Beitrag, verlinkt am Ende). Über Thermostate, die nach einem Neustart Standby anzeigen, habe ich schon geschrieben, einschließlich der Start-Automation, die das umgeht. Auf der alten Instanz ist diese Automation seit Januar ausgeschaltet, und dieser Vergleich zeigte das Symptom auf beiden Instanzen.
Ich hielt Z-BMU für ein Statusobjekt
Der ETS-Export führt pro Raumregler zwei Objekte. Eines heißt BMU plus Raum, für Betriebsmodus-Umschaltung. Daneben steht eines namens Z-BMU plus Raum, mit dem Datentyp für Betriebsarten. Ich habe das Z als Zustand gelesen, und das Muster passte für alle 11 Räume. Ich hielt diese 11 Adressen für die Statusadressen, die mir fehlten.
Z steht für Zwangsführung. Das Objekt ist nicht lesbar. Genau diese Adressen hatte ich früher schon einmal als falsche Rückmeldung aus der Konfiguration entfernt, und das ist im Repository dokumentiert. Aufgefallen ist es mir, weil ich vor dem erneuten Eintragen der Adressen in dieser Doku nachgesehen habe.
Abkürzungen in einem ETS-Projekt sind herstellerspezifisch. Bevor ich jetzt eine Adresse als Statusadresse eintrage, öffne ich das Objekt im ETS und sehe mir seine Flags an. Für die Abfrage nach einem Neustart brauche ich ein Objekt, das die aktive Betriebsart liefert und Leseanfragen beantwortet, und das sagt mir der Objektname nicht.
Was vor der Übernahme durch die neue Instanz noch fehlt
Nach einem Neustart können beide Instanzen die falsche Betriebsart anzeigen, bis sie einen Wechsel auf dem Bus mitlesen oder selbst einen schreiben. Ich hatte unterschätzt, wie wichtig die seit Januar deaktivierte Start-Automation für die Anzeige der Betriebsart ist. Beim Übertragen hatte sie eine Inkonsistenz: nachts setzte sie Economy, während die Nachtmodus-Automation Standby setzte. Am 9. Oktober habe ich mich für Economy entschieden. Es gilt nachts jetzt in der Fenster-, der Nacht- und der Start-Automation. Außerdem habe ich initial: off beim Nachtmodus-Helfer entfernt, weil der Helfer damit nach jedem Neustart aus war und die Start-Automation nachts Komfort gesetzt hätte. Jetzt stellt er seinen vorherigen Zustand wieder her; war Home Assistant zur Umschaltzeit aus, kann dieser allerdings noch falsch sein.
Als Nächstes muss ich im ETS prüfen, ob diese Regler ein lesbares Objekt für die aktive Betriebsart anbieten. Wenn ja, bekommt es eine eigene Gruppenadresse, und die trage ich in die Home-Assistant-Konfiguration ein. Die Automationen habe ich übertragen, bevor ich das geprüft hatte. Bis dahin ist die gemeldete Soll-Temperatur der beste Hinweis, den ich habe, wobei auch eine lokale Verstellung am Regler sie verschiebt, wie in dem Beitrag zu Basis und wirksamem Sollwert beschrieben.
Häufige Fragen
Warum zeigt ein KNX-Thermostat in Home Assistant nach einem Neustart Standby?
Bei mir liest die Abfrage nach einem Neustart das Objekt, über das die Betriebsart geschaltet wird, und das liefert Standby, auch wenn Komfort aktiv ist. Das gilt für dieses eine ETS-Projekt, andere kenne ich nicht.
Wie prüfe ich, ob eine KNX-Gruppenadresse als Statusadresse taugt?
Im ETS prüfen, ob das Objekt hinter der Gruppenadresse die aktive Betriebsart meldet und das Lesen-Flag gesetzt hat. Der Objektname ist kein Beleg, weil Abkürzungen herstellerspezifisch sind.
Ist eine Automation mit Zuordnungstabelle besser als eine Automation pro Raum?
Für meine 8 Räume ja. Ich ändere die Fensterlogik an einer Stelle statt in 16 Automationen und bearbeite dafür eine YAML-Datei mit Template statt der Oberfläche.



