feat: Werks-Token im Einrichtungsdialog vorbelegen

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.
This commit is contained in:
ninharp
2026-09-22 17:48:53 +02:00
parent adec66a6a2
commit 5ac410a416
5 changed files with 109 additions and 37 deletions
+4 -3
View File
@@ -23,6 +23,7 @@ from .api import NinstripAuthError, NinstripClient, NinstripError, NinstripRespo
from .const import (
CONF_SCAN_INTERVAL,
DEFAULT_SCAN_INTERVAL,
DEFAULT_TOKEN,
DOMAIN,
MAX_SCAN_INTERVAL,
MIN_SCAN_INTERVAL,
@@ -94,7 +95,7 @@ class NinstripConfigFlow(ConfigFlow, domain=DOMAIN):
data_schema=vol.Schema(
{
vol.Required(CONF_HOST, default=self._host): str,
vol.Required(CONF_TOKEN): str,
vol.Required(CONF_TOKEN, default=DEFAULT_TOKEN): str,
}
),
errors=errors,
@@ -117,7 +118,7 @@ class NinstripConfigFlow(ConfigFlow, domain=DOMAIN):
async def async_step_discovery_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Das Token steht einmalig auf der seriellen Konsole - es muss von Hand herein."""
"""Vorbelegt mit dem Werks-Token - ein frisch onboardetes Geraet antwortet damit."""
errors: dict[str, str] = {}
if user_input is not None:
info, errors = await self._async_probe(self._host, user_input[CONF_TOKEN])
@@ -125,7 +126,7 @@ class NinstripConfigFlow(ConfigFlow, domain=DOMAIN):
return await self._async_finish(self._host, user_input[CONF_TOKEN], info)
return self.async_show_form(
step_id="discovery_confirm",
data_schema=vol.Schema({vol.Required(CONF_TOKEN): str}),
data_schema=vol.Schema({vol.Required(CONF_TOKEN, default=DEFAULT_TOKEN): str}),
description_placeholders={"name": self._discovered_name, "host": self._host},
errors=errors,
)
+5
View File
@@ -6,6 +6,11 @@ from typing import Final
DOMAIN: Final = "ninstrip"
# Oeffentliches Werks-Token der Firmware (NL_DEFAULT_TOKEN), dasselbe wie bei
# ninlight. Ein Geraet im Auslieferungszustand und nach jedem Werksreset
# antwortet damit - deshalb belegt der Einrichtungsdialog es vor.
DEFAULT_TOKEN: Final = "aabbccddeeff0011223344"
CONF_SCAN_INTERVAL: Final = "scan_interval"
DEFAULT_PORT: Final = 3333
+49 -16
View File
@@ -3,18 +3,25 @@
"step": {
"user": {
"title": "ninstrip hinzufügen",
"description": "Adresse und API-Token des Geräts. Das Token wird beim ersten Start einmalig auf der seriellen Konsole ausgegeben; ein Werksreset erzeugt ein neues.",
"data": { "host": "Adresse", "token": "API-Token" }
"description": "Adresse und API-Token des Geräts. Im Auslieferungszustand und nach einem Werksreset gilt das Werks-Token, das bereits eingetragen ist. Wer ein eigenes gesetzt hat, trägt es hier ein.",
"data": {
"host": "Adresse",
"token": "API-Token"
}
},
"discovery_confirm": {
"title": "ninstrip gefunden",
"description": "{name} unter {host}. Bitte das API-Token eingeben.",
"data": { "token": "API-Token" }
"data": {
"token": "API-Token"
}
},
"reauth_confirm": {
"title": "Token erneuern",
"description": "Das Gerät unter {host} weist das gespeicherte Token ab. Nach einem Werksreset hat es ein neues.",
"data": { "token": "API-Token" }
"description": "Das Gerät unter {host} weist das gespeicherte Token ab. Nach einem Werksreset gilt wieder das Werks-Token.",
"data": {
"token": "API-Token"
}
}
},
"error": {
@@ -32,24 +39,50 @@
"step": {
"init": {
"title": "Einstellungen",
"data": { "scan_interval": "Abfrageabstand (Sekunden)" }
"data": {
"scan_interval": "Abfrageabstand (Sekunden)"
}
}
}
},
"entity": {
"select": { "preset": { "name": "Szene" } },
"button": { "restart": { "name": "Neu starten" } },
"select": {
"preset": {
"name": "Szene"
}
},
"button": {
"restart": {
"name": "Neu starten"
}
},
"sensor": {
"rssi": { "name": "WLAN-Signal" },
"uptime": { "name": "Laufzeit" },
"free_heap": { "name": "Freier Speicher" },
"power_scale": { "name": "Leistungsbegrenzung" }
"rssi": {
"name": "WLAN-Signal"
},
"uptime": {
"name": "Laufzeit"
},
"free_heap": {
"name": "Freier Speicher"
},
"power_scale": {
"name": "Leistungsbegrenzung"
}
}
},
"exceptions": {
"auth_failed": { "message": "Das Gerät hat das Token abgelehnt." },
"device_busy": { "message": "Das Gerät ist beschäftigt - vermutlich läuft eine Aktualisierung." },
"request_failed": { "message": "Das Gerät hat die Anfrage abgewiesen: {message}" },
"cannot_connect": { "message": "Das Gerät ist nicht erreichbar." }
"auth_failed": {
"message": "Das Gerät hat das Token abgelehnt."
},
"device_busy": {
"message": "Das Gerät ist beschäftigt - vermutlich läuft eine Aktualisierung."
},
"request_failed": {
"message": "Das Gerät hat die Anfrage abgewiesen: {message}"
},
"cannot_connect": {
"message": "Das Gerät ist nicht erreichbar."
}
}
}
+49 -16
View File
@@ -3,18 +3,25 @@
"step": {
"user": {
"title": "ninstrip hinzufügen",
"description": "Adresse und API-Token des Geräts. Das Token wird beim ersten Start einmalig auf der seriellen Konsole ausgegeben; ein Werksreset erzeugt ein neues.",
"data": { "host": "Adresse", "token": "API-Token" }
"description": "Adresse und API-Token des Geräts. Im Auslieferungszustand und nach einem Werksreset gilt das Werks-Token, das bereits eingetragen ist. Wer ein eigenes gesetzt hat, trägt es hier ein.",
"data": {
"host": "Adresse",
"token": "API-Token"
}
},
"discovery_confirm": {
"title": "ninstrip gefunden",
"description": "{name} unter {host}. Bitte das API-Token eingeben.",
"data": { "token": "API-Token" }
"data": {
"token": "API-Token"
}
},
"reauth_confirm": {
"title": "Token erneuern",
"description": "Das Gerät unter {host} weist das gespeicherte Token ab. Nach einem Werksreset hat es ein neues.",
"data": { "token": "API-Token" }
"description": "Das Gerät unter {host} weist das gespeicherte Token ab. Nach einem Werksreset gilt wieder das Werks-Token.",
"data": {
"token": "API-Token"
}
}
},
"error": {
@@ -32,24 +39,50 @@
"step": {
"init": {
"title": "Einstellungen",
"data": { "scan_interval": "Abfrageabstand (Sekunden)" }
"data": {
"scan_interval": "Abfrageabstand (Sekunden)"
}
}
}
},
"entity": {
"select": { "preset": { "name": "Szene" } },
"button": { "restart": { "name": "Neu starten" } },
"select": {
"preset": {
"name": "Szene"
}
},
"button": {
"restart": {
"name": "Neu starten"
}
},
"sensor": {
"rssi": { "name": "WLAN-Signal" },
"uptime": { "name": "Laufzeit" },
"free_heap": { "name": "Freier Speicher" },
"power_scale": { "name": "Leistungsbegrenzung" }
"rssi": {
"name": "WLAN-Signal"
},
"uptime": {
"name": "Laufzeit"
},
"free_heap": {
"name": "Freier Speicher"
},
"power_scale": {
"name": "Leistungsbegrenzung"
}
}
},
"exceptions": {
"auth_failed": { "message": "Das Gerät hat das Token abgelehnt." },
"device_busy": { "message": "Das Gerät ist beschäftigt - vermutlich läuft eine Aktualisierung." },
"request_failed": { "message": "Das Gerät hat die Anfrage abgewiesen: {message}" },
"cannot_connect": { "message": "Das Gerät ist nicht erreichbar." }
"auth_failed": {
"message": "Das Gerät hat das Token abgelehnt."
},
"device_busy": {
"message": "Das Gerät ist beschäftigt - vermutlich läuft eine Aktualisierung."
},
"request_failed": {
"message": "Das Gerät hat die Anfrage abgewiesen: {message}"
},
"cannot_connect": {
"message": "Das Gerät ist nicht erreichbar."
}
}
}
@@ -3,7 +3,7 @@
"step": {
"user": {
"title": "Add ninstrip",
"description": "Host and API token of the device. The token is printed once on the serial console at first boot; a factory reset creates a new one.",
"description": "Host and API token of the device. A factory-new or factory-reset device uses the default token, which is prefilled. If you set your own, enter it here.",
"data": {
"host": "Host",
"token": "API token"
@@ -18,7 +18,7 @@
},
"reauth_confirm": {
"title": "Renew token",
"description": "The device at {host} rejects the stored token. After a factory reset it has a new one.",
"description": "The device at {host} rejects the stored token. After a factory reset the default token applies again.",
"data": {
"token": "API token"
}