|
|
@@ -84,10 +84,15 @@ class ZLockCoordinator(DataUpdateCoordinator[dict[str, LockState]]):
|
|
|
stored = await self._store.async_load()
|
|
|
if stored:
|
|
|
self._names = stored.get("names", {})
|
|
|
- # TODO: restore last_action/last_user for each lock and group from stored
|
|
|
- # "last_events": {"lock_entity_id": {"last_action": ..., "last_user": ...}}
|
|
|
- # Door state is unlikely to have changed since last run, so stale values
|
|
|
- # are better than None until the next real event arrives.
|
|
|
+ last_events = stored.get("last_events", {})
|
|
|
+ for eid, ev in last_events.get("locks", {}).items():
|
|
|
+ if eid in self.data:
|
|
|
+ self.data[eid].last_action = ev.get("last_action")
|
|
|
+ self.data[eid].last_user = ev.get("last_user")
|
|
|
+ for gname, ev in last_events.get("groups", {}).items():
|
|
|
+ if gname in self.group_data:
|
|
|
+ self.group_data[gname].last_action = ev.get("last_action")
|
|
|
+ self.group_data[gname].last_user = ev.get("last_user")
|
|
|
|
|
|
await self._async_fetch_all_slots()
|
|
|
|
|
|
@@ -169,18 +174,36 @@ class ZLockCoordinator(DataUpdateCoordinator[dict[str, LockState]]):
|
|
|
self.group_data[group_name].last_action = mapping.action
|
|
|
self.group_data[group_name].last_user = user_str
|
|
|
|
|
|
+ self.hass.async_create_task(self._async_save())
|
|
|
self.async_update_listeners()
|
|
|
|
|
|
def get_name(self, lock_entity_id: str, slot_num: int) -> str | None:
|
|
|
return self._names.get(f"{lock_entity_id}:{slot_num}")
|
|
|
|
|
|
+ async def _async_save(self) -> None:
|
|
|
+ await self._store.async_save({
|
|
|
+ "names": self._names,
|
|
|
+ "last_events": {
|
|
|
+ "locks": {
|
|
|
+ eid: {"last_action": s.last_action, "last_user": s.last_user}
|
|
|
+ for eid, s in self.data.items()
|
|
|
+ if s.last_action is not None or s.last_user is not None
|
|
|
+ },
|
|
|
+ "groups": {
|
|
|
+ gname: {"last_action": g.last_action, "last_user": g.last_user}
|
|
|
+ for gname, g in self.group_data.items()
|
|
|
+ if g.last_action is not None or g.last_user is not None
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+
|
|
|
async def async_set_name(self, lock_entity_id: str, slot_num: int, name: str) -> None:
|
|
|
key = f"{lock_entity_id}:{slot_num}"
|
|
|
if name:
|
|
|
self._names[key] = name
|
|
|
else:
|
|
|
self._names.pop(key, None)
|
|
|
- await self._store.async_save({"names": self._names})
|
|
|
+ await self._async_save()
|
|
|
|
|
|
state = self.data.get(lock_entity_id)
|
|
|
if state and slot_num in state.slots:
|