Store Schlage coordinator data as a plain dict (#178342)

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
David Knowles
2026-08-06 13:55:07 +02:00
committed by GitHub
co-authored by Claude Opus 5
parent 25ce314b87
commit fc49ae57b9
8 changed files with 17 additions and 26 deletions
@@ -54,7 +54,7 @@ async def async_setup_entry(
for description in _DESCRIPTIONS
)
_add_new_locks(coordinator.data.locks)
_add_new_locks(coordinator.data)
coordinator.new_locks_callbacks.append(_add_new_locks)
@@ -26,17 +26,10 @@ class LockData:
logs: list[LockLog]
@dataclass
class SchlageData:
"""Container for cached data from the Schlage API."""
locks: dict[str, LockData]
type SchlageConfigEntry = ConfigEntry[SchlageDataUpdateCoordinator]
class SchlageDataUpdateCoordinator(DataUpdateCoordinator[SchlageData]):
class SchlageDataUpdateCoordinator(DataUpdateCoordinator[dict[str, LockData]]):
"""The Schlage data update coordinator."""
config_entry: SchlageConfigEntry
@@ -56,13 +49,13 @@ class SchlageDataUpdateCoordinator(DataUpdateCoordinator[SchlageData]):
name=f"{DOMAIN} ({username})",
update_interval=UPDATE_INTERVAL,
)
self.data = SchlageData(locks={})
self.data = {}
self.api = api
self.new_locks_callbacks: list[Callable[[dict[str, LockData]], None]] = []
self.async_add_listener(self._add_remove_locks)
@override
async def _async_update_data(self) -> SchlageData:
async def _async_update_data(self) -> dict[str, LockData]:
"""Fetch the latest data from the Schlage API."""
try:
locks = await self.hass.async_add_executor_job(self.api.locks)
@@ -78,12 +71,12 @@ class SchlageDataUpdateCoordinator(DataUpdateCoordinator[SchlageData]):
for lock in locks
)
)
return SchlageData(locks={ld.lock.device_id: ld for ld in lock_data})
return {ld.lock.device_id: ld for ld in lock_data}
def _get_lock_data(self, lock: Lock) -> LockData:
logs: list[LockLog] = []
previous_lock_data = None
if self.data and (previous_lock_data := self.data.locks.get(lock.device_id)):
if self.data and (previous_lock_data := self.data.get(lock.device_id)):
# Default to the previous data, in case a refresh fails.
# It's not critical if we don't have the freshest data.
logs = previous_lock_data.logs
@@ -111,7 +104,7 @@ class SchlageDataUpdateCoordinator(DataUpdateCoordinator[SchlageData]):
previous_locks.add(identifier)
previous_locks_by_lock_id[identifier] = device
continue
current_locks = set(self.data.locks.keys())
current_locks = set(self.data.keys())
if removed_locks := previous_locks - current_locks:
LOGGER.debug("Removed locks: %s", ", ".join(removed_locks))
@@ -122,6 +115,6 @@ class SchlageDataUpdateCoordinator(DataUpdateCoordinator[SchlageData]):
if new_lock_ids := current_locks - previous_locks:
LOGGER.debug("New locks found: %s", ", ".join(new_lock_ids))
new_locks = {lock_id: self.data.locks[lock_id] for lock_id in new_lock_ids}
new_locks = {lock_id: self.data[lock_id] for lock_id in new_lock_ids}
for new_lock_callback in self.new_locks_callbacks:
new_lock_callback(new_locks)
@@ -14,6 +14,4 @@ async def async_get_config_entry_diagnostics(
"""Return diagnostics for a config entry."""
coordinator = config_entry.runtime_data
# NOTE: Schlage diagnostics are already redacted.
return {
"locks": [ld.lock.get_diagnostics() for ld in coordinator.data.locks.values()]
}
return {"locks": [ld.lock.get_diagnostics() for ld in coordinator.data.values()]}
+2 -2
View File
@@ -34,7 +34,7 @@ class SchlageEntity(CoordinatorEntity[SchlageDataUpdateCoordinator]):
@property
def _lock_data(self) -> LockData:
"""Fetch the LockData from our coordinator."""
return self.coordinator.data.locks[self.device_id]
return self.coordinator.data[self.device_id]
@property
def _lock(self) -> Lock:
@@ -47,6 +47,6 @@ class SchlageEntity(CoordinatorEntity[SchlageDataUpdateCoordinator]):
"""Return if entity is available."""
return (
super().available
and self.device_id in self.coordinator.data.locks
and self.device_id in self.coordinator.data
and self._lock.connected
)
+2 -2
View File
@@ -29,7 +29,7 @@ async def async_setup_entry(
for device_id in locks
)
_add_new_locks(coordinator.data.locks)
_add_new_locks(coordinator.data)
coordinator.new_locks_callbacks.append(_add_new_locks)
@@ -49,7 +49,7 @@ class SchlageLockEntity(SchlageEntity, LockEntity):
@override
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
if self.device_id in self.coordinator.data.locks:
if self.device_id in self.coordinator.data:
self._update_attrs()
super()._handle_coordinator_update()
+1 -1
View File
@@ -41,7 +41,7 @@ async def async_setup_entry(
for description in _DESCRIPTIONS
)
_add_new_locks(coordinator.data.locks)
_add_new_locks(coordinator.data)
coordinator.new_locks_callbacks.append(_add_new_locks)
+2 -2
View File
@@ -45,7 +45,7 @@ async def async_setup_entry(
for device_id in locks
)
_add_new_locks(coordinator.data.locks)
_add_new_locks(coordinator.data)
coordinator.new_locks_callbacks.append(_add_new_locks)
@@ -68,6 +68,6 @@ class SchlageBatterySensor(SchlageEntity, SensorEntity):
@override
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
if self.device_id in self.coordinator.data.locks:
if self.device_id in self.coordinator.data:
self._attr_native_value = getattr(self._lock, self.entity_description.key)
super()._handle_coordinator_update()
+1 -1
View File
@@ -70,7 +70,7 @@ async def async_setup_entry(
for description in SWITCHES
)
_add_new_locks(coordinator.data.locks)
_add_new_locks(coordinator.data)
coordinator.new_locks_callbacks.append(_add_new_locks)