fix: alarm code sensor registers on stub resources, shows all active codes

Two fixes for the alarm_code diagnostic sensor:

1. _is_included now treats an empty rep ({}) from /device/0 as a stub
   meaning the resource exists but hasn't been individually fetched yet.
   Previously the field-presence check against {} returned False, leaving
   the entity unregistered and showing Unavailable from the entity registry.

2. Replace _last_alarm_code (silently dropped all but the final alarm) with
   _active_alarm_codes which joins all codes in the items list. Shows 'none'
   when no alarms are active.
This commit is contained in:
Marc Billow
2026-06-30 23:02:11 -05:00
parent 022a192bca
commit 62fc3b44f4
2 changed files with 15 additions and 6 deletions
+9 -1
View File
@@ -20,11 +20,19 @@ def _is_included(bound: BoundEntity, coordinator: 'LocalThingsCoordinator') -> b
Explicit exists_fn takes priority. Otherwise, if the entity has a field,
require that field to be present in the resource rep so that optional
fields on shared resources don't create phantom entities.
An empty rep ({}) means /device/0 returned a stub for this resource —
the resource exists on the device but data hasn't been fetched yet.
In that case we include the entity so it can be populated by sub-polls.
"""
rep = coordinator.last_resources.get(bound.href) or {}
rep = coordinator.last_resources.get(bound.href)
if rep is None:
return False
if bound.desc.exists_fn is not None:
return bound.desc.exists_fn(rep)
if bound.desc.field:
if not rep: # stub — resource known to exist, data not yet fetched
return True
return bound.desc.field in rep
return True # rep_fn or no-field entities (ButtonDesc) are always included
@@ -36,10 +36,11 @@ def _ml_to_l(v):
return round(n / 1000.0, 1) if n is not None else None
def _last_alarm_code(items):
if items and isinstance(items, list):
return items[-1].get('x.com.samsung.da.code')
return None
def _active_alarm_codes(items):
if not items or not isinstance(items, list):
return 'none'
codes = [i.get('x.com.samsung.da.code') for i in items if i.get('x.com.samsung.da.code')]
return ', '.join(codes) if codes else 'none'
KIDS_LOCK = Capability(
@@ -77,7 +78,7 @@ ALARMS = Capability(
entities=(
SensorDesc(key='alarm_code', field='x.com.samsung.da.items',
name='Alarm code', icon='mdi:alert',
entity_category='diagnostic', value_fn=_last_alarm_code),
entity_category='diagnostic', value_fn=_active_alarm_codes),
),
)