Fix handling of powerview stale state (#70195)

This commit is contained in:
J. Nick Koston 2022-04-17 19:31:48 -10:00 committed by Paulus Schoutsen
parent 40ba0e0aed
commit bc2c4a41b8

View File

@ -46,10 +46,12 @@ _LOGGER = logging.getLogger(__name__)
# Estimated time it takes to complete a transition # Estimated time it takes to complete a transition
# from one state to another # from one state to another
TRANSITION_COMPLETE_DURATION = 30 TRANSITION_COMPLETE_DURATION = 40
PARALLEL_UPDATES = 1 PARALLEL_UPDATES = 1
RESYNC_DELAY = 60
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
@ -103,6 +105,9 @@ def hass_position_to_hd(hass_position):
class PowerViewShade(ShadeEntity, CoverEntity): class PowerViewShade(ShadeEntity, CoverEntity):
"""Representation of a powerview shade.""" """Representation of a powerview shade."""
# The hub frequently reports stale states
_attr_assumed_state = True
def __init__(self, coordinator, device_info, room_name, shade, name): def __init__(self, coordinator, device_info, room_name, shade, name):
"""Initialize the shade.""" """Initialize the shade."""
super().__init__(coordinator, device_info, room_name, shade, name) super().__init__(coordinator, device_info, room_name, shade, name)
@ -112,6 +117,7 @@ class PowerViewShade(ShadeEntity, CoverEntity):
self._last_action_timestamp = 0 self._last_action_timestamp = 0
self._scheduled_transition_update = None self._scheduled_transition_update = None
self._current_cover_position = MIN_POSITION self._current_cover_position = MIN_POSITION
self._forced_resync = None
@property @property
def extra_state_attributes(self): def extra_state_attributes(self):
@ -224,10 +230,12 @@ class PowerViewShade(ShadeEntity, CoverEntity):
@callback @callback
def _async_cancel_scheduled_transition_update(self): def _async_cancel_scheduled_transition_update(self):
"""Cancel any previous updates.""" """Cancel any previous updates."""
if not self._scheduled_transition_update: if self._scheduled_transition_update:
return self._scheduled_transition_update()
self._scheduled_transition_update() self._scheduled_transition_update = None
self._scheduled_transition_update = None if self._forced_resync:
self._forced_resync()
self._forced_resync = None
@callback @callback
def _async_schedule_update_for_transition(self, steps): def _async_schedule_update_for_transition(self, steps):
@ -260,6 +268,14 @@ class PowerViewShade(ShadeEntity, CoverEntity):
_LOGGER.debug("Processing scheduled update for %s", self.name) _LOGGER.debug("Processing scheduled update for %s", self.name)
self._scheduled_transition_update = None self._scheduled_transition_update = None
await self._async_force_refresh_state() await self._async_force_refresh_state()
self._forced_resync = async_call_later(
self.hass, RESYNC_DELAY, self._async_force_resync
)
async def _async_force_resync(self, *_):
"""Force a resync after an update since the hub may have stale state."""
self._forced_resync = None
await self._async_force_refresh_state()
async def _async_force_refresh_state(self): async def _async_force_refresh_state(self):
"""Refresh the cover state and force the device cache to be bypassed.""" """Refresh the cover state and force the device cache to be bypassed."""
@ -274,10 +290,14 @@ class PowerViewShade(ShadeEntity, CoverEntity):
self.coordinator.async_add_listener(self._async_update_shade_from_group) self.coordinator.async_add_listener(self._async_update_shade_from_group)
) )
async def async_will_remove_from_hass(self):
"""Cancel any pending refreshes."""
self._async_cancel_scheduled_transition_update()
@callback @callback
def _async_update_shade_from_group(self): def _async_update_shade_from_group(self):
"""Update with new data from the coordinator.""" """Update with new data from the coordinator."""
if self._scheduled_transition_update: if self._scheduled_transition_update or self._forced_resync:
# If a transition in in progress # If a transition in in progress
# the data will be wrong # the data will be wrong
return return