From 5c8e5a7af2fce45b921750f0485457183e9dc527 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Wed, 30 Aug 2023 13:14:30 +0200 Subject: [PATCH] Split bsblan coordinator and randomize update interval (#99269) * Split out bsblan coordinator and randomize update interval * Use logger const * Add randomising update interval for following updates * Implement review comments * Re-add config_entry * Remove line --- homeassistant/components/bsblan/__init__.py | 11 ++-- .../components/bsblan/coordinator.py | 54 +++++++++++++++++++ 2 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 homeassistant/components/bsblan/coordinator.py diff --git a/homeassistant/components/bsblan/__init__.py b/homeassistant/components/bsblan/__init__.py index 0ef3ed159a6..224cb479dda 100644 --- a/homeassistant/components/bsblan/__init__.py +++ b/homeassistant/components/bsblan/__init__.py @@ -15,7 +15,8 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import DataUpdateCoordinator -from .const import CONF_PASSKEY, DOMAIN, LOGGER, SCAN_INTERVAL +from .const import CONF_PASSKEY, DOMAIN +from .coordinator import BSBLanUpdateCoordinator PLATFORMS = [Platform.CLIMATE] @@ -44,13 +45,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: session=session, ) - coordinator: DataUpdateCoordinator[State] = DataUpdateCoordinator( - hass, - LOGGER, - name=f"{DOMAIN}_{entry.data[CONF_HOST]}", - update_interval=SCAN_INTERVAL, - update_method=bsblan.state, - ) + coordinator = BSBLanUpdateCoordinator(hass, entry, bsblan) await coordinator.async_config_entry_first_refresh() device = await bsblan.device() diff --git a/homeassistant/components/bsblan/coordinator.py b/homeassistant/components/bsblan/coordinator.py new file mode 100644 index 00000000000..9344500a118 --- /dev/null +++ b/homeassistant/components/bsblan/coordinator.py @@ -0,0 +1,54 @@ +"""DataUpdateCoordinator for the BSB-Lan integration.""" +from __future__ import annotations + +from datetime import timedelta +from random import randint + +from bsblan import BSBLAN, BSBLANConnectionError +from bsblan.models import State + +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_HOST +from homeassistant.core import HomeAssistant +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed + +from .const import DOMAIN, LOGGER, SCAN_INTERVAL + + +class BSBLanUpdateCoordinator(DataUpdateCoordinator[State]): + """The BSB-Lan update coordinator.""" + + config_entry: ConfigEntry + + def __init__( + self, + hass: HomeAssistant, + config_entry: ConfigEntry, + client: BSBLAN, + ) -> None: + """Initialize the BSB-Lan coordinator.""" + + self.client = client + + super().__init__( + hass, + LOGGER, + name=f"{DOMAIN}_{config_entry.data[CONF_HOST]}", + # use the default scan interval and add a random number of seconds to avoid timeouts when + # the BSB-Lan device is already/still busy retrieving data, e.g. for MQTT or internal logging. + update_interval=SCAN_INTERVAL + timedelta(seconds=randint(1, 8)), + ) + + async def _async_update_data(self) -> State: + """Get state from BSB-Lan device.""" + + # use the default scan interval and add a random number of seconds to avoid timeouts when + # the BSB-Lan device is already/still busy retrieving data, e.g. for MQTT or internal logging. + self.update_interval = SCAN_INTERVAL + timedelta(seconds=randint(1, 8)) + + try: + return await self.client.state() + except BSBLANConnectionError as err: + raise UpdateFailed( + f"Error while establishing connection with BSB-Lan device at {self.config_entry.data[CONF_HOST]}" + ) from err