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:
parent
20d0362914
commit
87c22c3ad5
2 changed files with 14 additions and 5 deletions
|
@ -345,10 +345,13 @@ async def async_setup_entry( # noqa: C901
|
||||||
disconnect_cb()
|
disconnect_cb()
|
||||||
entry_data.disconnect_callbacks = []
|
entry_data.disconnect_callbacks = []
|
||||||
entry_data.available = False
|
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
|
# the next state update of that type when the device reconnects
|
||||||
for state_keys in entry_data.state.values():
|
entry_data.stale_state = {
|
||||||
state_keys.clear()
|
(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:
|
if not hass.is_stopping:
|
||||||
# Avoid marking every esphome entity as unavailable on shutdown
|
# Avoid marking every esphome entity as unavailable on shutdown
|
||||||
# since it generates a lot of state changed events and database
|
# since it generates a lot of state changed events and database
|
||||||
|
|
|
@ -70,6 +70,10 @@ class RuntimeEntryData:
|
||||||
client: APIClient
|
client: APIClient
|
||||||
store: Store
|
store: Store
|
||||||
state: dict[type[EntityState], dict[int, EntityState]] = field(default_factory=dict)
|
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)
|
info: dict[str, dict[int, EntityInfo]] = field(default_factory=dict)
|
||||||
|
|
||||||
# A second list of EntityInfo objects
|
# A second list of EntityInfo objects
|
||||||
|
@ -206,9 +210,11 @@ class RuntimeEntryData:
|
||||||
"""Distribute an update of state information to the target."""
|
"""Distribute an update of state information to the target."""
|
||||||
key = state.key
|
key = state.key
|
||||||
state_type = type(state)
|
state_type = type(state)
|
||||||
|
stale_state = self.stale_state
|
||||||
current_state_by_type = self.state[state_type]
|
current_state_by_type = self.state[state_type]
|
||||||
current_state = current_state_by_type.get(key, _SENTINEL)
|
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(
|
_LOGGER.debug(
|
||||||
"%s: ignoring duplicate update with and key %s: %s",
|
"%s: ignoring duplicate update with and key %s: %s",
|
||||||
self.name,
|
self.name,
|
||||||
|
@ -222,8 +228,8 @@ class RuntimeEntryData:
|
||||||
key,
|
key,
|
||||||
state,
|
state,
|
||||||
)
|
)
|
||||||
|
stale_state.discard(subscription_key)
|
||||||
current_state_by_type[key] = state
|
current_state_by_type[key] = state
|
||||||
subscription_key = (state_type, key)
|
|
||||||
if subscription_key in self.state_subscriptions:
|
if subscription_key in self.state_subscriptions:
|
||||||
self.state_subscriptions[subscription_key]()
|
self.state_subscriptions[subscription_key]()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue