diff --git a/homeassistant/components/overkiz/__init__.py b/homeassistant/components/overkiz/__init__.py index ab463fc34d9a20..d714a9898ca295 100644 --- a/homeassistant/components/overkiz/__init__.py +++ b/homeassistant/components/overkiz/__init__.py @@ -27,11 +27,12 @@ DOMAIN, LOGGER, OVERKIZ_DEVICE_TO_PLATFORM, + OVERKIZ_REFRESH_DEVICE_STATES_DEVICES, PLATFORMS, UPDATE_INTERVAL, UPDATE_INTERVAL_ALL_ASSUMED_STATE, ) -from .coordinator import OverkizDataUpdateCoordinator +from .coordinator import OverkizDataUpdateCoordinator, OverkizDeviceRefreshCoordinator @dataclass @@ -39,6 +40,7 @@ class HomeAssistantOverkizData: """Overkiz data stored in the Home Assistant data object.""" coordinator: OverkizDataUpdateCoordinator + device_refresh_coordinators: list[OverkizDeviceRefreshCoordinator] platforms: defaultdict[Platform, list[Device]] scenarios: list[Scenario] @@ -96,12 +98,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ) coordinator.update_interval = UPDATE_INTERVAL_ALL_ASSUMED_STATE + device_refresh_coordinators: list[OverkizDeviceRefreshCoordinator] = [] platforms: defaultdict[Platform, list[Device]] = defaultdict(list) - hass.data.setdefault(DOMAIN, {})[entry.entry_id] = HomeAssistantOverkizData( - coordinator=coordinator, platforms=platforms, scenarios=scenarios - ) - # Map Overkiz entities to Home Assistant platform for device in coordinator.data.values(): LOGGER.debug( @@ -117,6 +116,23 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ) or OVERKIZ_DEVICE_TO_PLATFORM.get(device.ui_class): platforms[platform].append(device) + if ( + device.widget in OVERKIZ_REFRESH_DEVICE_STATES_DEVICES + or device.ui_class in OVERKIZ_REFRESH_DEVICE_STATES_DEVICES + ): + device_refresh_coordinator = OverkizDeviceRefreshCoordinator( + hass, LOGGER, client=client, device_url=device.device_url + ) + await device_refresh_coordinator.async_request_refresh() + device_refresh_coordinators.append(device_refresh_coordinator) + + hass.data.setdefault(DOMAIN, {})[entry.entry_id] = HomeAssistantOverkizData( + coordinator=coordinator, + device_refresh_coordinators=device_refresh_coordinators, + platforms=platforms, + scenarios=scenarios, + ) + device_registry = dr.async_get(hass) for gateway in setup.gateways: diff --git a/homeassistant/components/overkiz/const.py b/homeassistant/components/overkiz/const.py index 102d09a76b1402..0eac421738cdb9 100644 --- a/homeassistant/components/overkiz/const.py +++ b/homeassistant/components/overkiz/const.py @@ -37,6 +37,8 @@ UPDATE_INTERVAL: Final = timedelta(seconds=30) UPDATE_INTERVAL_ALL_ASSUMED_STATE: Final = timedelta(minutes=60) +REFRESH_DEVICE_STATES_INTERVAL: Final = timedelta(minutes=5) + PLATFORMS: list[Platform] = [ Platform.ALARM_CONTROL_PANEL, Platform.BINARY_SENSOR, @@ -59,6 +61,11 @@ UIClass.POD, ] +OVERKIZ_REFRESH_DEVICE_STATES_DEVICES: list[UIClass | UIWidget] = [ + UIClass.GARAGE_DOOR, + UIClass.GATE, +] + # Used to map the Somfy widget and ui_class to the Home Assistant platform OVERKIZ_DEVICE_TO_PLATFORM: dict[UIClass | UIWidget, Platform | None] = { UIClass.ADJUSTABLE_SLATS_ROLLER_SHUTTER: Platform.COVER, diff --git a/homeassistant/components/overkiz/coordinator.py b/homeassistant/components/overkiz/coordinator.py index 7c9cab5f181de4..3e881ac12448bd 100644 --- a/homeassistant/components/overkiz/coordinator.py +++ b/homeassistant/components/overkiz/coordinator.py @@ -25,7 +25,7 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.util.decorator import Registry -from .const import DOMAIN, LOGGER, UPDATE_INTERVAL +from .const import DOMAIN, LOGGER, REFRESH_DEVICE_STATES_INTERVAL, UPDATE_INTERVAL EVENT_HANDLERS: Registry[ str, Callable[[OverkizDataUpdateCoordinator, Event], Coroutine[Any, Any, None]] @@ -209,3 +209,32 @@ async def on_execution_state_changed( ExecutionState.FAILED, ]: del coordinator.executions[event.exec_id] + + +class OverkizDeviceRefreshCoordinator(DataUpdateCoordinator[None]): + """Class to trigger device state refresh for devices on Overkiz platform.""" + + def __init__( + self, + hass: HomeAssistant, + logger: logging.Logger, + *, + client: OverkizClient, + device_url: str, + ) -> None: + """Initialize data update coordinator.""" + self.client = client + self.device_url = device_url + super().__init__( + hass, + logger, + name=f"device refresh for {device_url}", + update_interval=REFRESH_DEVICE_STATES_INTERVAL, + ) + + # Ensure this coordinator runs periodically even though there is no listener needed. + self.async_add_listener(lambda: None) + + async def _async_update_data(self) -> None: + """Trigger device state refresh on Overkiz platform.""" + await self.client.refresh_device_states(self.device_url)