Loading...
E.G.

KNX-Schalter aus der Home-Assistant-UI nach knx.yaml

14. Oktober 2026
Teil 6 von 6Serie: KNX in Home AssistantAlle Teile
  1. 01KNX-Bewegungsmelder-Automationen in Home Assistant
  2. 02KNX-Thermostat-Voreinstellungen in Home Assistant
  3. 03KNX-Thermostate stehen nach jedem Home-Assistant-Neustart auf 'Standby' — die Startup-Automation, die den richtigen Modus setzt
  4. 04Fenster auf, Heizung aus: KNX-Thermostat pro Raum automatisch auf Frostschutz schalten (Home Assistant)
  5. 05Eine KNX-Alarmanlage in Home Assistant vom JUNG-Panel entkoppeln
  6. 06KNX-Schalter aus der Home-Assistant-UI nach knx.yaml
Inhaltsverzeichnis

Rund ein Jahr lang hatte ich 33 KNX-Schalter in Home Assistant, die nur in der Oberfläche existierten. Ich hatte sie im Entitäten-Editor der KNX-Integration zusammengeklickt, als die Beleuchtung auf zwei Etagen, das Garagentor und zwei Hilfsschalter angeschlossen wurden, und es ging schnell. Home Assistant legt diese Schalter in einer JSON-Datei unter .storage ab, die es selbst überschreibt und die nicht in meinem Git-Repository liegt. Thermostate, Rollos und Sensoren desselben Busses liegen seit Anfang an in der knx.yaml, neben der Startup-Automation und der Fensterlogik. Im September habe ich 31 davon nachgezogen und zwei gestrichen, die ich nicht mehr als Schalter haben wollte. Die Vorbereitung hat eine Woche gedauert, die Umstellung selbst etwa zehn Minuten.

Warum ich die UI-Einträge vor dem Laden der YAML gelöscht habe

Die KNX-Integration liest beim Laden sowohl den UI-Store als auch die knx.yaml und legt für jede Definition eine Entität an. Ein Schalter, der an beiden Stellen definiert ist, existiert doppelt, mit zwei Entity-IDs, und nichts warnt davor. Hätte ich zuerst das YAML ergänzt und die UI-Einträge danach gelöscht, wären 31 Duplikate entstanden. Ich habe deshalb zuerst die UI-Entitäten gelöscht und danach das YAML geladen. Die Konfigurationsprüfung der neuen Datei lief bei mir ebenfalls erst nach dem Löschen, das ist Schritt 2 unten. Ein YAML-Fehler wäre aufgefallen, als die Schalter schon weg waren. Beim nächsten Mal würde ich die Prüfung vor Schritt 1 machen. Zwischen Löschen und Neuladen gibt es die Schalter nicht. In dieser Zeit lassen sie sich im Dashboard nicht bedienen, und Automationsaktionen für diese Schalter schlagen fehl.

Bis zur Migration lag auf der Maschine eine Deploy-Variante der knx.yaml, identisch mit der Repository-Version, nur ohne den Block für die 31 Schalter, die noch in der UI verwaltet wurden, mit einem Kommentar oben, der das sagt. Hätte ich versehentlich die vollständige Datei übertragen, wären die Schalter doppelt angelegt worden. Das war der zweite Grund, warum ich diese gesonderte Datei loswerden wollte.

Wie ein Schalter in YAML aussieht

Im YAML stehen weitgehend dieselben Einstellungen wie in der JSON-Datei des UI-Editors, nur in einer Datei, die ich bearbeiten und in Git ablegen kann. Zwei Details darin waren bewusste Änderungen gegenüber dem, was ich ein Jahr vorher zusammengeklickt hatte:

# knx.yaml — zwei Schalterdefinitionen, mit und ohne Rückmeldeadresse
switch:
  - name: "Licht 1"
    address: "1/2/3"          # Gruppenadresse, auf die der Aktor hört
    state_address: "1/3/3"    # Rückmeldeobjekt, falls der Aktor eines hat
    sync_state: true
  - name: "Deckenlicht"
    address: "1/2/4"
    # keine state_address: der Aktor hat kein Rückmeldeobjekt.
    # Die zentrale Statusadresse habe ich entfernt, weil Leseanfragen dort unbeantwortet blieben.

Neun Schalter hatten als Statusadresse eine zentrale Statusadresse, auf der der Aktor nie geantwortet hat. Home Assistant fragte sie ab, bekam nichts und zeigte den Zustand, den es zuletzt angenommen hatte. Im YAML habe ich diese Adresse bei allen neun entfernt. Zwei davon nutzen jetzt ihr echtes Rückmeldeobjekt, die anderen sieben haben keine Statusadresse, Home Assistant zeigt bei ihnen also, was es zuletzt gesendet hat.

Das Werkzeug: vier Befehle über die Websocket-API

Ich habe dafür ein lokales Node-Skript mit vier Unterbefehlen verwendet. Die Befehle unten sind die, die ich ausgeführt habe. Das Skript selbst und die gespeicherte Zuordnung von Gruppenadresse zu alter Entity-ID stehen nicht in diesem Beitrag, nur der Kern des Rename-Schritts weiter unten. Das Skript nutzt dieselbe Websocket-API wie das Frontend und meldet sich mit einem langlebigen Zugriffstoken an. Vor dem ersten Löschen habe ich den KNX-Store, die Entity-Registry und die ausgerollte knx.yaml zusammen gesichert. Das Unterscheidungsmerkmal der beiden Entitätsarten ist die Unique-ID: UI-Entitäten tragen eine ID, die mit knx_es_ beginnt, YAML-Entitäten tragen die Gruppenadresse selbst.

# 0. Bestand: 33 UI-Entitäten, 2 YAML-Schalter erwartet
node tools/knx_migrate_ui_switches.mjs list

# 1. UI-Entitäten aus dem KNX-Config-Store löschen (Websocket knx/delete_entity)
node tools/knx_migrate_ui_switches.mjs delete-ui

# 2. die volle knx.yaml auf die Maschine und prüfen
scp knx.yaml ha-host:/tmp/knx.yaml
ssh ha-host 'sudo cp /tmp/knx.yaml /home/ha/config/knx.yaml \
  && sudo docker exec homeassistant python -m homeassistant --script check_config -c /config'

# 3. Integration neu laden (kein Neustart), warten, alte Entity-IDs zurücksetzen
node tools/knx_migrate_ui_switches.mjs reload     # ruft knx.reload
sleep 20
node tools/knx_migrate_ui_switches.mjs rename     # setzt je Schalter die bisherige entity_id
node tools/knx_migrate_ui_switches.mjs list       # jede Zeile muss OK zeigen

Der Löschschritt benutzt je Entität den Websocket-Befehl knx/delete_entity, denselben, den der UI-Editor beim Druck auf das Papierkorbsymbol aufruft. Home Assistant entfernt die Entität aus dem KNX-Store und aus der Entity-Registry. Dieser zweite Teil ist der Grund, warum es den Rename-Schritt gibt.

Die Entity-IDs behalten

Beim Neuladen legt Home Assistant die YAML-Entitäten an und leitet ihre Entity-IDs aus den Namen ab. Wo eine neue Entity-ID von der bisherigen abwich, hätte ich jede Dashboard-Karte und jede Automation anpassen müssen, die sie verwendet. Der Rename-Schritt vermeidet das. Das Skript nimmt die gespeicherte Zuordnung von Gruppenadresse zu bisheriger Entity-ID, sucht die neue YAML-Entität anhand ihrer Unique-ID und setzt über die Registry-API wieder die bisherige Entity-ID.

// der Kern von "rename": entity_registry/update über die Websocket-API
// MAPPING: Gruppenadresse (write) -> die entity_id, die die UI-Entität hatte
for (const [ga, oldId] of Object.entries(MAPPING)) {
  const yamlEntity = registry.find((e) => e.platform === "knx" && e.unique_id === ga);
  if (!yamlEntity || yamlEntity.entity_id === oldId) continue;
  await ws.send({ type: "config/entity_registry/update",
                  entity_id: yamlEntity.entity_id, new_entity_id: oldId });
}

Zwischen Reload und Rename habe ich 20 Sekunden gewartet. Die KNX-Integration registriert ihre Entitäten asynchron, nachdem der Reload-Aufruf zurückkommt, und mein Skript überspringt jede Entität, die es in der Registry noch nicht findet, ohne Fehlermeldung. Ich hatte list einmal zu früh laufen lassen, und die Hälfte der Entitäten fehlte. 20 Sekunden haben hier gereicht, und wie kurz die Wartezeit sein dürfte, habe ich nicht gemessen.

Das abschließende list zeigte 0 UI-Entitäten und 33 YAML-Schalter, das sind die 31 übernommenen und zwei, die schon vorher im YAML standen. Alle 31 übernommenen Schalter hatten wieder ihre bisherige Entity-ID. Nach der Übernahme waren alle 31 Entitäten wieder ihren bisherigen Bereichen zugeordnet, und die zwei Labels, nach denen eine Zeitsteuerungs-Automation filtert, waren wie vorher gesetzt. Der Rename-Ausschnitt oben zeigt diesen Teil nicht.

Fünf Automationsaktionen, die danach nicht mehr funktionierten

Die Entity-IDs waren wiederhergestellt, und trotzdem funktionierten fünf Aktionen in drei Automationen nicht mehr. Sie waren im Automations-Editor als Geräteaktionen angelegt worden, und die binden an die interne Geräte-ID der Registry. Mit dem Löschen der UI-Entitäten waren diese Geräte weg, und die Aktionen zeigten ins Leere. Home Assistant ließ die drei Automationen deshalb nicht fehlschlagen. Es schrieb beim Ausführen eine Warnung ins Log und übersprang die Aktion.

# vorher: eine Geräteaktion, gebunden an eine Registry-Geräte-ID, die es nicht mehr gibt
- device_id: 3f1c…a97e
  domain: switch
  type: turn_on
  entity_id: 9b2d…c410

# nachher: dieselbe Aktion auf der stabilen Entity-ID
- action: switch.turn_on
  target:
    entity_id: switch.licht_1

Ich habe alle fünf durch einfache switch.turn_on- und switch.turn_off-Aktionen auf den Entity-IDs ersetzt und die Automationen neu geladen. Aktionen, die deaktiviert waren, blieben deaktiviert. Danach meldete die vollständige Konfigurationsprüfung keine Fehler, und im Log fand ich keine Meldungen über unbekannte Entitäten. Seitdem schreibe ich neue Automationsaktionen als Entitätsaktionen mit switch.turn_on und switch.turn_off, so wie es die aufgeteilten YAML-Dateien schon tun.

Was ich getestet habe, und was nicht ging

Ich habe vier Schalter aus Home Assistant ein- und ausgeschaltet, dabei die ausgehenden Bustelegramme geprüft und danach den ursprünglichen Aus-Zustand wiederhergestellt. Für die Lampen ohne Rückmeldeobjekt ist das keine unabhängige Bestätigung, weil Home Assistant nur weiß, was es gesendet hat. Das Garagentor habe ich vor Ort mit zwei Impulsen getestet und die Rückmeldung geprüft: 0 beim Öffnen, 1 nach dem Schließen. In der Doku steht jetzt, dass turn_on einen Impuls auslöst und die Fahrtrichtung damit nicht festgelegt ist.

Der Recorder schrieb während der Umbenennungen 28 Warnungen, weil die alten Ziel-IDs bereits Historie hatten und die kurze Historie unter den Zwischennamen nicht zusammengeführt wird. Die Datenbank habe ich in Ruhe gelassen. Die Wiederherstellung des alten Stands habe ich nie getestet. Dafür müsste ich KNX-Store, Entity-Registry und die alte knx.yaml gemeinsam aus der Sicherung von vor dem Löschen zurückspielen. Dafür muss Home Assistant vorher gestoppt sein, sonst überschreibt es die zurückgespielten .storage-Dateien wieder. Am produktiven Bus wollte ich das nicht für eine Migration ausprobieren, die schon gelungen war.

Häufige Fragen

Kann ich einige KNX-Entitäten in der UI und andere in YAML lassen?

Ja, solange jeder Schalter nur an einer der beiden Stellen definiert ist. Sonst gibt es ihn doppelt.

Warum nicht einfach die UI-Konfiguration exportieren?

Es gibt keinen Export. Der Store ist eine lesbare JSON-Datei unter .storage/knx. Sie enthält die Einstellungen, aus denen ein Skript die YAML-Konfiguration erzeugen kann. Der list-Befehl meines Skripts macht im Kern diese Übersetzung und zeigt die Einträge aus dem UI-Store neben den YAML-Definitionen an.

Vermeidet knx.reload wirklich einen Neustart?

Für die KNX-Integration selbst ja. Sie baut ihre Entitäten ab und neu auf und liest die knx.yaml neu ein. Die Automationen bleiben in dieser Zeit aktiv. Eine kann also laufen, während die Entität fehlt, die sie schalten soll. Nach einer späteren Änderung an den Statusadressen der Thermostate habe ich Home Assistant vollständig neu gestartet. Das Neuladen ohne Neustart habe ich also nur bei dieser Schalter-Übernahme getestet.

Fragen oder Ergänzungen?

Die Kommentare laufen über GitHub Discussions, zum Schreiben brauchst du ein GitHub-Konto.

Verwandte Artikel