Skip to content

Commit dcb235f

Browse files
authored
Refresh devices when there are structure chagnes (#1218)
1 parent b5a9493 commit dcb235f

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

google_nest_sdm/device.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,16 @@ def _async_handle_traits(self, event_message: EventMessage) -> None:
292292
traits = event_message.resource_update_traits
293293
if not traits:
294294
return
295-
_LOGGER.debug("Trait update %s", traits)
296295
# Parse the traits using a separate object, then overwrite
297296
# each present field with an updated copy of the original trait with
298297
# the new fields merged in.
298+
_LOGGER.debug("Trait update %s", traits)
299299
parsed_traits = TraitTypes.parse_trait_object({TRAITS: traits})
300+
self._async_update_traits(parsed_traits, event_message.timestamp)
301+
302+
def _async_update_traits(
303+
self, parsed_traits: TraitTypes, timestamp: datetime.datetime
304+
) -> None:
300305
for trait_field in fields(parsed_traits):
301306
if (
302307
(alias := trait_field.metadata.get("alias")) is None
@@ -308,9 +313,9 @@ def _async_handle_traits(self, event_message: EventMessage) -> None:
308313
if (
309314
self._trait_event_ts
310315
and (ts := self._trait_event_ts.get(trait_field.name))
311-
and ts > event_message.timestamp
316+
and ts > timestamp
312317
):
313-
_LOGGER.debug("Discarding stale update (%s)", event_message.timestamp)
318+
_LOGGER.debug("Discarding stale update (%s)", timestamp)
314319
continue
315320

316321
# Only merge updates into existing models, updating the existing
@@ -320,7 +325,14 @@ def _async_handle_traits(self, event_message: EventMessage) -> None:
320325
for k, v in asdict(new).items():
321326
if v is not None:
322327
setattr(existing, k, v)
323-
self._trait_event_ts[trait_field.name] = event_message.timestamp
328+
self._trait_event_ts[trait_field.name] = timestamp
329+
330+
def merge_from_update(self, new_device: Device) -> None:
331+
"""Merge fields from an updated device object.
332+
333+
This is used when refreshing the device list from the API.
334+
"""
335+
self._async_update_traits(new_device, datetime.datetime.utcnow())
324336

325337
@property
326338
def event_media_manager(self) -> EventMediaManager:

google_nest_sdm/device_manager.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,13 @@ async def async_handle_event(self, event_message: EventMessage) -> None:
6969
return
7070

7171
if event_message.relation_update:
72+
_LOGGER.debug("Handling relation update: %s", event_message.relation_update)
7273
self._handle_device_relation(event_message.relation_update)
74+
# Also discover any new devices/structures
75+
try:
76+
await self.async_refresh()
77+
except ApiException:
78+
_LOGGER.debug("Failed to refresh devices")
7379
if self._update_callback:
7480
await self._update_callback(event_message)
7581
return
@@ -119,19 +125,27 @@ async def async_refresh(self) -> None:
119125
}
120126
for structure in new_structures.values():
121127
if structure.name not in self._structures:
128+
_LOGGER.debug("Adding structure %s", structure.name)
122129
self._structures[structure.name] = structure
123130
removed_structure_ids = old_structure_ids - set(new_structures.keys())
124131
for structure_id in removed_structure_ids:
132+
_LOGGER.debug("Removing structure %s", structure_id)
125133
del self._structures[structure_id]
126134

127135
# Refresh devices
128136
devices = await self._api.async_get_devices()
129137
old_device_ids = set(self._devices.keys())
130138
new_devices = {device.name: device for device in devices if device.name}
131139
for device in new_devices.values():
132-
self._add_device(device)
140+
if existing_device := self._devices.get(device.name):
141+
existing_device.merge_from_update(device)
142+
else:
143+
_LOGGER.debug("Adding device %s", device.name)
144+
self._add_device(device)
145+
133146
removed_device_ids = old_device_ids - set(new_devices.keys())
134147
for device_id in removed_device_ids:
148+
_LOGGER.debug("Removing device %s", device_id)
135149
del self._devices[device_id]
136150

137151
if self._change_callback and (

0 commit comments

Comments
 (0)