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 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.