Die neun Effekte der Firmware waren in Home Assistant nicht erreichbar -
das Auswahlfeld, das es schon gab, sind die Szenen. Jetzt bietet die
Lichtentitaet sie an:
* Gewaehlt wird ueber den NAMEN aus der Firmware ("Regenbogen"),
geschickt wird die Kennung ("rainbow"). Eine Liste englischer
Kennungen waere in einer deutschen Oberflaeche unnoetig sperrig.
* Ein Effekt laeuft wie eine Farbe in ALLEN Segmenten; angezeigt wird er
nur, wenn alle denselben fahren.
* Eine Kennung, die nicht in der Liste steht (neuere Firmware, aeltere
Liste), wird roh angezeigt statt verschluckt.
* Ein unbekannter Name wird abgelehnt, statt stillschweigend nichts zu
tun.
Die Liste steht fest in der Firmware und wird deshalb einmal geholt,
nicht je Abfragezyklus - erneut erst, wenn sich die Version aendert. Eine
sechste Anfrage je Zyklus fuer etwas, das sich nie aendert, waere
Verschwendung.
Effekt-Parameter (Geschwindigkeit, Intensitaet, Palette) fehlen noch;
dafuer braucht es Entitaeten je Segment.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Michaels Befund: die Integration ist nicht dasselbe wie die von ninlight.
Verglichen und die Luecken geschlossen - alle Felder gibt es in der
Firmware schon, sie waren nur nicht bedienbar:
* number: fade_in, fade_out, transition_default in Millisekunden, mit den
Grenzen der Firmware (10 s, 10 s, 60 s).
* select: Einschaltverhalten (last, on, off).
* switch: bei Aenderung einschalten.
* light: Uebergangszeit beim Ein- und Ausschalten. HA rechnet in Sekunden,
das Geraet in Millisekunden; laengeres als 60 s wird gekappt, sonst
wiese das Geraet die ganze Anfrage mit 400 ab. Ohne Angabe wird kein
Feld geschickt, sonst ueberschriebe jeder Schaltbefehl die Vorgabe.
* sensor: letzter Update-Fehler und Startzeit (Zeitstempel statt einer
Laufzeit, die jede Abfrage weiterlaeuft), beide ab Werk aus.
* diagnostics.py: Diagnosedaten zum Herunterladen, ohne Token, Adressen,
MAC und SSID.
* config_flow: Neu-Konfigurieren von Adresse und Token, mit Gegenprobe der
MAC - ein Tippfehler in der Adresse soll nicht still den falschen
Eintrag umbiegen.
* Hinweis in den Reparaturen, wenn ein Geraet noch auf dem oeffentlichen
Werks-Token steht.
Nicht uebernommen: die Auswahl sacn_layout. ninstrip ist immer rgb, ein
Strip hat keinen Masterkanal - eine Auswahl mit einer Option waere nur
Zierde.
241 Tests, 97 %. Die Kappung der Uebergangszeit per Mutation gegengeprueft.
In Home Assistant liessen sich nur Szenen und Helligkeit stellen, keine
Farben - device/state traegt naemlich keine. Die steht je Segment, und die
Segmente hat der Koordinator bisher gar nicht gelesen.
Jetzt holt er device/segments mit (fuenfte Anfrage je Zyklus), und die
Lichtentitaet bietet rgb_color und color_temp_kelvin an:
* Setzen schreibt in ALLE Segmente, aber nur die Farbfelder - Grenzen,
Namen und Helligkeit bleiben stehen. Die Einteilung eines Strips ist von
Hand gemacht, die reisst eine Farbwahl nicht ein. Geschrieben wird die
ganze Liste auf einmal, danach zurueckgelesen statt angenommen.
* Angezeigt wird nur, worauf sich alle Segmente einigen. Zwei Farben und
eine Entitaet - da waere jede Angabe gelogen, also gibt es keine.
* Farbtemperatur nur, wenn alle auf "white" stehen; sonst RGB, sonst
blendete HA den Farbkreis aus, sobald ein Segment einen Effekt faehrt.
* Die Farbe geht VOR dem Einschalten raus, sonst leuchtet der Strip kurz
in der alten auf.
Die Spanne 2700-6500 K ist die, die die Firmware auf die Weisskanaele
umrechnet (nl_ct.h); ohne Weisskanaele naehert sie sie in RGB an.
Dazu: das Markenbild ist jetzt dasselbe wie bei ninlight - Michaels
Wunsch, die beiden Integrationen gehoeren zusammen. Das Skript fuer ein
eigenes Motiv bleibt als Ausgangspunkt liegen.
In der Geraeteuebersicht stand bei ninstrip nur ein Platzhalter. Ab HA
2026.3 nimmt Home Assistant die Bilder aus custom_components/<domain>/brand/;
ha-ninlight macht es genauso, dort mit einer Gluehbirne.
Gezeichnet wird mit scripts/make_brand.py, damit das Motiv nachvollziehbar
bleibt und sich in einer Zeile aendern laesst.
In ha-dev brach jeder Versuch, den Abfrageabstand oder die HA-Adresse zu
sichern, mit einem 500er ab. Im Protokoll stand der Grund:
ValueError: Config entry update listeners should not be used with
OptionsFlowWithReload
Der Eintrag meldete zusaetzlich einen add_update_listener an, der beim
Aendern neu laedt - genau das macht OptionsFlowWithReload aber schon
selbst, und Home Assistant weist die Kombination rundheraus ab. Der
Listener faellt weg.
Die Tests in test_config_flow.py konnten das nicht sehen: dort ist
async_setup_entry durchweg ersetzt, der Eintrag wird also nie wirklich
aufgesetzt und meldet auch keinen Listener an. Der neue Test in
test_init.py laeuft am eingerichteten Eintrag und faellt, wenn man den
Listener wieder einbaut - gegengeprueft.
Michaels Wunsch: die Adresse soll man sehen, ohne erst einen Sensor
einzuschalten - man braucht sie fuer die Firmware-API, zum Anpingen oder
um ein Geraet wiederzufinden. ha-ninlight macht es genauso.
WLAN-Signal, Laufzeit und freier Speicher bleiben aus: die braucht man
erst im Fehlerfall.
Aufgebaut wie ha-ninlight: die Abbilder liegen unter ninstrip_firmware im
Konfigurationsverzeichnis, Home Assistant liefert sie selbst unter einer
einmaligen Adresse aus, und zwar genau die Bytes, die vorher geprueft
wurden. Dazu firmware.py (Anhaenger, Versionsreihenfolge, WLAN-Pruefung,
Katalog), http.py, urls.py und shared.py.
Drei Unterschiede zu ninlight, alle aus der Firmware heraus:
* Verglichen wird device_type - die Platine -, nicht product. Letzteres ist
bei allen Platinen 'ninstrip'; die Abbilder unterscheiden sich aber hart,
die K1Y invertiert das Datensignal und die KL-RGBC3 nicht. Firmware ohne
dieses Feld bekommt gar kein Angebot.
* Die WLAN-Pruefung sucht die SSID unverpackt: ein ESP32-Abbild ist nicht
gzip-verpackt wie das des W600. An einem mit sdkconfig.local gebauten
Abbild gegengeprueft - die SSID steht genau einmal NUL-gerahmt drin.
* Der Fehlerschluessel heisst device_url_too_long statt lamp_url_too_long.
Dazu das Testgeruest, das es hier bisher gar nicht gab: 204 Tests in
tests_unit/ (ohne HA-Instanz) und tests/ (mit), Abdeckung 97 %, dazu
scripts/check.sh als Ersatz fuer die fehlende CI. Die Nutzdaten in
tests_unit/samples.py sind an der Stehlampe abgefragt.
Beim Gegenpruefen per Mutation fiel auf, dass die Platinenpruefung
unmittelbar vor dem Senden ungeprueft war - der Test dazu ist jetzt da und
faellt, wenn man die Pruefung entfernt.
Die Firmware kann sACN/E1.31 - jetzt auch in Home Assistant, aufgebaut wie in
ha-ninlight: Schalter fuer den Empfang, Zahlen fuer Universe und Startslot,
Auswahl fuer das Verhalten nach Stromende, zwei Diagnose-Binaersensoren.
Die Einstellungen liegen hinter system/settings, der Koordinator liest sie
deshalb mit - eine vierte Anfrage je Zyklus. Nach dem Schreiben wird
zurueckgelesen statt angenommen, wie in ha-ninlight.
Zwei Unterschiede zu ninlight:
- Kein Layout-Feld: ninstrip nutzt fest drei Kanaele je Pixel.
- Der Startslot gilt in JEDEM belegten Universe. Die Obergrenze ist deshalb
513 minus Kanaele je Pixel, also 510 - ein festes 512 boete Werte an, bei
denen kein einziges Pixel mehr ins Universe passt.
Aeltere Firmware ohne sacn-Block: die Entitaeten entstehen trotzdem und
melden sich nicht verfuegbar, bis ein Update kommt.
In ha-dev an der Stehlampe geprueft: Universe, Startslot, on_timeout und der
Schalter kommen jeweils auf dem Geraet an; der Aktiv-Sensor steht waehrend
eines Stroms auf an, danach auf aus. 511 als Startslot weist Home Assistant
selbst ab ("outside valid range 1 - 510"). Einstellungen der Lampe danach
zurueckgestellt.
Die README behauptete noch, das Token stehe einmalig auf der seriellen
Konsole - seit der Umstellung auf das Werks-Token wie ninlight falsch.
Dazu die Vertrauensgrenze, die bisher nur in der Firmware stand: wer im
selben WLAN ist und das oeffentliche Token kennt, kann das Geraet steuern und
Firmware aufspielen. Bewusst so, wie bei ninlight. Eine automatische
Sicherheitspruefung hatte die Vorbelegung im Dialog beanstandet - die
Begruendung gehoert deshalb auch hierher, nicht nur in die Firmware.
Die Firmware antwortet im Auslieferungszustand und nach jedem Werksreset mit
dem oeffentlichen Werks-Token aabbccddeeff0011223344 - genau wie ninlight.
Wie ha-ninlight belegt die Integration es deshalb im Dialog vor, beim
manuellen Einrichten, beim Fund per mDNS und in den Texten zur
Token-Erneuerung.
Auf dem Geruest von ha-ninlight aufgebaut und bewusst parallel gehalten:
gleiche Fehlerklassen in api.py, gleicher Coordinator mit Sperre und
Fehlertoleranz, gleicher Einrichtungsablauf samt Zeroconf und Reauth.
Eigenes Repo statt Erweiterung von ha-ninlight: die Geraete melden sich unter
verschiedenen mDNS-Diensten, das Datenmodell unterscheidet sich deutlich
(Segmente und Szenen gegen ein einzelnes Licht), und ha-ninlight laeuft
produktiv mit vier Lampen - Verzweigungen dort haetten beide Produkte
gefaehrdet.
Entitaeten: light (Hauptschalter und Helligkeit), select (Szene), button
(Neustart), vier Diagnosesensoren.
In ha-dev eingebunden und am echten Geraet geprueft: Aus- und Einschalten,
Helligkeit 40 Prozent, Szenenwechsel auf Regenbogen - das Geraet meldet
jeweils genau das zurueck.