Fix dryer detection when description pairs two model numbers (issue #79)

DVE50A8600V/A3 reports description
'DA_WM_TP1_21_COMMON_DVE50A8800_8600/DC92-02835A_0080' -- a paired
listing of two related model numbers (DVE50A8800 and DVE50A8600) joined
by an underscore, rather than the usual single trailing consumer-model
token. for_device_by_model only ever checked the literal last
underscore segment ('8600', which has no recognizable 2-letter prefix
on its own), so the real 'DV' token one segment earlier was never
reached and the device fell back to 'unknown' with only common
capabilities -- no dry level, cycle, or wrinkle-prevent entities.

Replace the single last-segment extraction with _consumer_model_key,
which scans segments from the end and returns the first one that
resolves. Behavior is unchanged for every existing single-token
description (the last segment still matches first); it just keeps
looking when that segment doesn't.
This commit is contained in:
Marc Billow committed 2026-07-27 00:44:23 +00:00
1 parent aff7647460
commit bae1ac4337
5 files changed
+488 -2

No files matched your search

@@ -87,6 +87,26 @@ _CONSUMER_PREFIX_TO_KEY: dict[str, str] = {
}
def _consumer_model_key(description: str) -> Optional[str]:
"""Registry key from the consumer-model token in `description`, or None.
Usually that token is the last '_'-delimited segment before any
'/board-info' suffix (e.g. '..._WW90DG6U25LEU4' -> 'WW90DG6U25LEU4').
But issue #79's dryer pairs two model numbers in one description --
'..._DVE50A8800_8600/DC92-...' -- so the true consumer token
('DVE50A8800') sits one segment *before* the actual last segment
('8600', a bare second model number with no recognizable prefix). Scan
segments from the end and take the first one that resolves, rather
than assuming the last segment is always it.
"""
segments = (description or '').split('/', 1)[0].split('_')
for segment in reversed(segments):
key = _CONSUMER_PREFIX_TO_KEY.get(segment[:2].upper())
if key is not None:
return key
return None
def for_device_by_model(model_num: str, description: str) -> Optional[DeviceRegistry]:
"""Fallback device-type detection for hardware that never reports
oneUiVersion (confirmed for washers -- their /otninformation/vs/0 has
@@ -100,8 +120,7 @@ def for_device_by_model(model_num: str, description: str) -> Optional[DeviceRegi
DeviceRegistry if the consumer-model code or modelNum resolves to a
known type, None otherwise.
"""
token = (description or '').split('/', 1)[0].rsplit('_', 1)[-1]
key = _CONSUMER_PREFIX_TO_KEY.get(token[:2].upper())
key = _consumer_model_key(description)
if key is None and '_REF_' in (model_num or ''):
key = 'refrigerator'
# Room air conditioners (e.g. ARTIK051_PRAC_20K) report no oneUiVersion and