Die Firmware wirbt im TXT-Satz nur mit den letzten vier Hex-Stellen der
MAC. Daraus wurde bisher direkt eine Kennung gebaut - die auf keinen
Eintrag passte. Folge: Home Assistant bot nach jedem Neustart dieselben,
laengst eingerichteten Strips erneut an, und beim Hinzufuegen kam
'bereits konfiguriert'.
Vier Stellen sind keine Kennung, aber ein Hinweis: endet genau ein
Eintrag so, ist er gemeint. Bei mehreren bleibt es unentschieden und der
Ablauf fragt nach - vier Stellen sind nicht eindeutig genug, um einen
fremden Eintrag stillschweigend umzuschreiben.
Die Tests sahen das nicht, weil ihr mDNS-Fixture die volle MAC eintrug -
eine Welt, die es am Geraet nicht gibt.
Zeigt strip.current_ma und strip.power_w aus system/info als Sensoren
und macht max_milliamps aus system/settings ueber ein Zahlenfeld
einstellbar. Schreiben liest wie bei sACN zurueck statt den
geschriebenen Wert anzunehmen.
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.