fix(config_flow): bekanntes Geraet auch an der verkuerzten mDNS-MAC erkennen

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.
This commit is contained in:
Michael Sauer
2026-09-26 01:05:25 +02:00
parent 616515ef77
commit d1db07f522
2 changed files with 70 additions and 2 deletions
+27 -2
View File
@@ -97,13 +97,38 @@ class NinstripConfigFlow(ConfigFlow, domain=DOMAIN):
errors=errors,
)
def _kennung_aus_mdns(self, roh: str) -> str | None:
"""Die Kennung zu dem, was im TXT-Satz unter "mac" steht.
Eine volle MAC ist die Kennung. Die Firmware wirbt aber nur mit den
letzten vier Hex-Stellen (`nl_wifi_mac4()`, siehe nl_mdns.c) - daraus
laesst sich keine bauen. Als *Hinweis* taugen sie trotzdem: endet
genau ein eingerichteter Eintrag so, ist er gemeint.
Bei mehreren Treffern bleibt es unentschieden. Dann lieber nachfragen
als den falschen Eintrag stillschweigend auf eine fremde Adresse
umzuschreiben - vier Stellen sind nicht eindeutig.
"""
kennung = format_mac(roh)
if len(kennung) == 17:
return kennung
kurz = roh.replace(":", "").replace("-", "").lower()
if len(kurz) != 4:
return None
treffer = [
eintrag.unique_id
for eintrag in self._async_current_entries(include_ignore=False)
if eintrag.unique_id and eintrag.unique_id.replace(":", "").endswith(kurz)
]
return treffer[0] if len(treffer) == 1 else None
async def async_step_zeroconf(self, discovery_info: ZeroconfServiceInfo) -> ConfigFlowResult:
"""Gefunden ueber _ninstrip._tcp."""
self._host = discovery_info.host
props = discovery_info.properties or {}
mac = props.get("mac")
if mac:
await self.async_set_unique_id(format_mac(str(mac)))
if mac and (kennung := self._kennung_aus_mdns(str(mac))):
await self.async_set_unique_id(kennung)
self._abort_if_unique_id_configured(updates={CONF_HOST: self._host})
self._discovered_name = str(props.get("name") or discovery_info.name.split(".")[0])
self.context["title_placeholders"] = {"name": self._discovered_name}