fix: recognize all-same-hex-digit placeholder serials (#189)

_is_placeholder_serial only caught the ARTIK051_DONGLE_REF family's
'Nothing(SVC)' sentinel. The DA_WM_A51_20_COMMON (ARTIK051) laundry
board family reports a different one instead -- every character the
same repeated hex digit -- which passed through as a real, non-unique
serial. Two different physical units (a washer and a dryer) both
reporting the literal serialNum 'FFFFFFFFFFFFFFF' collided on the
config-entry unique_id, so the second device's config flow aborted as
already configured. Widen the check (both the config_flow.py and
coordinator.py copies) to also catch that sentinel shape.
This commit is contained in:
Marc Billow committed 2026-07-31 01:59:49 +00:00
1 parent 822c6814b6
commit e642db462d
4 files changed
+93 -7

No files matched your search

+16 -1
View File
@@ -215,8 +215,23 @@ def _is_placeholder_serial(serial: str) -> bool:
serial` check here (and the equivalent one in coordinator.py's
`_run_discovery`) doesn't catch it, and two such units get the same
config-entry unique_id / entity unique_ids and collide (issue #83).
Issue #189: the DA_WM_A51_20_COMMON (ARTIK051) laundry board family
reports a flash-unset sentinel instead -- every character the same
repeated hex digit (a washer and a dryer, two different physical
units, both reported the literal serialNum 'FFFFFFFFFFFFFFF') -- which
the 'nothing' check above doesn't catch either, so the second unit's
config flow aborted as already configured.
"""
return serial.strip().lower().startswith('nothing')
s = serial.strip()
if s.lower().startswith('nothing'):
return True
upper = s.upper()
return (
len(upper) >= 8
and len(set(upper)) == 1
and upper[0] in '0123456789ABCDEF'
)
def _probe_and_validate(host: str, ca_cert_pem: str, ca_key_pem: str) -> dict:
+23 -5
View File
@@ -92,12 +92,30 @@ def _is_placeholder_serial(serial: str) -> bool:
serial` check below doesn't catch it, and `device_serial` feeds both
the HA device-registry identifier and every entity's unique_id
(entity.py), so two such units on the same install silently collide
and the second one's entities get dropped (issue #83). Mirrors the
identical helper in config_flow.py's `_probe_and_validate` -- kept
separate rather than imported to avoid pulling the config-flow module
into the runtime coordinator's import graph for a two-line check.
and the second one's entities get dropped (issue #83).
Issue #189: the DA_WM_A51_20_COMMON (ARTIK051) laundry board family
reports a flash-unset sentinel instead -- every character the same
repeated hex digit (a washer and a dryer, two different physical
units, both reported the literal serialNum 'FFFFFFFFFFFFFFF') -- which
the 'nothing' check above doesn't catch either, so two such units
collided on the config-entry unique_id and the second couldn't be
added at all.
Mirrors the identical helper in config_flow.py's `_probe_and_validate`
-- kept separate rather than imported to avoid pulling the config-flow
module into the runtime coordinator's import graph for a two-line
check.
"""
return serial.strip().lower().startswith('nothing')
s = serial.strip()
if s.lower().startswith('nothing'):
return True
upper = s.upper()
return (
len(upper) >= 8
and len(set(upper)) == 1
and upper[0] in '0123456789ABCDEF'
)
class LocalThingsCoordinator(DataUpdateCoordinator[dict[str, Any]]):