feat: nachgezogen, was ha-ninlight laengst hat

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.
This commit is contained in:
Michael Sauer
2026-09-23 00:35:12 +02:00
parent c40c68b537
commit 9eb7adcdd7
18 changed files with 737 additions and 20 deletions
@@ -22,6 +22,14 @@
"data": {
"token": "API-Token"
}
},
"reconfigure": {
"title": "Gerät ändern",
"description": "Adresse und API-Token des Geräts {host}. Die MAC wird gegengeprüft — ein anderes Gerät wird abgelehnt.",
"data": {
"host": "Adresse",
"token": "API-Token"
}
}
},
"error": {
@@ -32,7 +40,9 @@
},
"abort": {
"already_configured": "Dieses Gerät ist bereits eingerichtet",
"reauth_successful": "Token erneuert"
"reauth_successful": "Token erneuert",
"wrong_device": "Dort antwortet ein anderes Gerät",
"reconfigure_successful": "Gerät geändert"
}
},
"options": {
@@ -64,6 +74,14 @@
"release": "Zurück zum vorherigen Bild",
"hold": "Letztes Bild halten"
}
},
"power_on_behaviour": {
"name": "Einschaltverhalten",
"state": {
"last": "Wie zuvor",
"on": "An",
"off": "Aus"
}
}
},
"button": {
@@ -86,11 +104,20 @@
},
"power_scale": {
"name": "Leistungsbegrenzung"
},
"last_ota_error": {
"name": "Letzter Update-Fehler"
},
"boot_time": {
"name": "Gestartet"
}
},
"switch": {
"sacn_enabled": {
"name": "sACN-Empfang"
},
"wake_on_change": {
"name": "Bei Änderung einschalten"
}
},
"number": {
@@ -99,6 +126,15 @@
},
"sacn_start_slot": {
"name": "sACN-Startslot"
},
"fade_in": {
"name": "Einblendzeit"
},
"fade_out": {
"name": "Ausblendzeit"
},
"transition_default": {
"name": "Übergangszeit (Vorgabe)"
}
},
"binary_sensor": {
@@ -157,6 +193,10 @@
"wifi_guard": {
"title": "Firmware für {name} wird nicht angeboten",
"description": "Im Firmware-Ordner liegt {version} für {device_type}, aber ohne WLAN-Zugangsdaten für {ssid}. Das Gerät kennt sein WLAN nur aus der Firmware und verlöre nach dieser Aktualisierung seine Netzverbindung. Deshalb wird sie nicht angeboten. Wer das Gerät stattdessen über das Onboarding ins WLAN gebracht hat, bekommt das Update ohne diesen Vorbehalt."
},
"default_token": {
"title": "{name} nutzt das öffentliche Werks-Token",
"description": "Mit dem öffentlichen Werks-Token kann jeder im selben Netz dieses Gerät umkonfigurieren, neu starten, neu flashen oder auf Werk zurücksetzen — dabei verliert es seine WLAN-Daten und fällt in den Onboarding-AP zurück. Schalten und Dimmen steht ohnehin jedem im Netz offen, solange `auth_all` aus ist. Setze am Gerät ein eigenes Token und trage es über „Neu konfigurieren\" ein."
}
}
}
@@ -22,6 +22,14 @@
"data": {
"token": "API token"
}
},
"reconfigure": {
"title": "Change device",
"description": "Address and API token of device {host}. The MAC is checked — a different device is rejected.",
"data": {
"host": "Address",
"token": "API token"
}
}
},
"error": {
@@ -32,7 +40,9 @@
},
"abort": {
"already_configured": "This device is already configured",
"reauth_successful": "Token renewed"
"reauth_successful": "Token renewed",
"wrong_device": "A different device answers there",
"reconfigure_successful": "Device changed"
}
},
"options": {
@@ -64,6 +74,14 @@
"release": "Return to previous image",
"hold": "Hold last image"
}
},
"power_on_behaviour": {
"name": "Power-on behaviour",
"state": {
"last": "As before",
"on": "On",
"off": "Off"
}
}
},
"button": {
@@ -86,11 +104,20 @@
},
"power_scale": {
"name": "Power limiting"
},
"last_ota_error": {
"name": "Last update error"
},
"boot_time": {
"name": "Started"
}
},
"switch": {
"sacn_enabled": {
"name": "sACN receiver"
},
"wake_on_change": {
"name": "Turn on when changed"
}
},
"number": {
@@ -99,6 +126,15 @@
},
"sacn_start_slot": {
"name": "sACN start slot"
},
"fade_in": {
"name": "Fade-in time"
},
"fade_out": {
"name": "Fade-out time"
},
"transition_default": {
"name": "Default transition time"
}
},
"binary_sensor": {
@@ -157,6 +193,10 @@
"wifi_guard": {
"title": "Firmware for {name} not offered",
"description": "The firmware folder contains {version} for {device_type}, but without Wi-Fi credentials for {ssid}. The device only knows its Wi-Fi from its firmware and would lose its network connection after this update, so the update is not offered. A device that was put on the network through onboarding instead gets the update without this reservation."
},
"default_token": {
"title": "{name} uses the public default token",
"description": "With the public default token, anyone on your network can reconfigure, restart, reflash or factory-reset this device, losing its Wi-Fi settings and falling back to its onboarding access point. Switching and dimming are open to anyone on the network anyway while `auth_all` is off. Set your own token on the device and enter it via \"Reconfigure\"."
}
}
}