Fix state being cleared on disconnect with deep sleep esphome devices (#90925)

* Fix state being cleared on disconnect with deep sleep esphome devices

fixes #90923

* fix logic
This commit is contained in:
J. Nick Koston 2023-04-06 10:32:02 -10:00 committed by GitHub
parent 20d0362914
commit 87c22c3ad5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 5 deletions

View file

@ -345,10 +345,13 @@ async def async_setup_entry( # noqa: C901
disconnect_cb()
entry_data.disconnect_callbacks = []
entry_data.available = False
# Clear out the states so that we will always dispatch
# Mark state as stale so that we will always dispatch
# the next state update of that type when the device reconnects
for state_keys in entry_data.state.values():
state_keys.clear()
entry_data.stale_state = {
(type(entity_state), key)
for state_dict in entry_data.state.values()
for key, entity_state in state_dict.items()
}
if not hass.is_stopping:
# Avoid marking every esphome entity as unavailable on shutdown
# since it generates a lot of state changed events and database

View file

@ -70,6 +70,10 @@ class RuntimeEntryData:
client: APIClient
store: Store
state: dict[type[EntityState], dict[int, EntityState]] = field(default_factory=dict)
# When the disconnect callback is called, we mark all states
# as stale so we will always dispatch a state update when the
# device reconnects. This is the same format as state_subscriptions.
stale_state: set[tuple[type[EntityState], int]] = field(default_factory=set)
info: dict[str, dict[int, EntityInfo]] = field(default_factory=dict)
# A second list of EntityInfo objects
@ -206,9 +210,11 @@ class RuntimeEntryData:
"""Distribute an update of state information to the target."""
key = state.key
state_type = type(state)
stale_state = self.stale_state
current_state_by_type = self.state[state_type]
current_state = current_state_by_type.get(key, _SENTINEL)
if current_state == state:
subscription_key = (state_type, key)
if current_state == state and subscription_key not in stale_state:
_LOGGER.debug(
"%s: ignoring duplicate update with and key %s: %s",
self.name,
@ -222,8 +228,8 @@ class RuntimeEntryData:
key,
state,
)
stale_state.discard(subscription_key)
current_state_by_type[key] = state
subscription_key = (state_type, key)
if subscription_key in self.state_subscriptions:
self.state_subscriptions[subscription_key]()