From 34a636ef0bab7ae9d513da94e723120186b42545 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sun, 6 Feb 2022 18:03:50 +0100 Subject: [PATCH] Extract Plugwise DataUpdateCoordinator into module (#65915) --- .../components/plugwise/binary_sensor.py | 12 +++---- homeassistant/components/plugwise/climate.py | 4 +-- .../components/plugwise/coordinator.py | 36 +++++++++++++++++++ homeassistant/components/plugwise/entity.py | 14 ++++---- homeassistant/components/plugwise/gateway.py | 28 ++------------- homeassistant/components/plugwise/sensor.py | 10 +++--- homeassistant/components/plugwise/switch.py | 4 +-- 7 files changed, 62 insertions(+), 46 deletions(-) create mode 100644 homeassistant/components/plugwise/coordinator.py diff --git a/homeassistant/components/plugwise/binary_sensor.py b/homeassistant/components/plugwise/binary_sensor.py index dfaea46c615..e83904ab25d 100644 --- a/homeassistant/components/plugwise/binary_sensor.py +++ b/homeassistant/components/plugwise/binary_sensor.py @@ -9,7 +9,6 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import ( COORDINATOR, @@ -22,6 +21,7 @@ from .const import ( NO_NOTIFICATION_ICON, NOTIFICATION_ICON, ) +from .coordinator import PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity SEVERITIES = ["other", "info", "warning", "error"] @@ -46,9 +46,9 @@ async def async_setup_entry( ) -> None: """Set up the Smile binary_sensors from a config entry.""" api: Smile = hass.data[DOMAIN][config_entry.entry_id]["api"] - coordinator: DataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id][ - COORDINATOR - ] + coordinator: PlugwiseDataUpdateCoordinator = hass.data[DOMAIN][ + config_entry.entry_id + ][COORDINATOR] entities: list[BinarySensorEntity] = [] is_thermostat = api.single_master_thermostat() @@ -95,7 +95,7 @@ class SmileBinarySensor(PlugwiseEntity, BinarySensorEntity): def __init__( self, api: Smile, - coordinator: DataUpdateCoordinator, + coordinator: PlugwiseDataUpdateCoordinator, name: str, dev_id: str, description: BinarySensorEntityDescription, @@ -151,7 +151,7 @@ class PwNotifySensor(SmileBinarySensor): def __init__( self, api: Smile, - coordinator: DataUpdateCoordinator, + coordinator: PlugwiseDataUpdateCoordinator, name: str, dev_id: str, description: BinarySensorEntityDescription, diff --git a/homeassistant/components/plugwise/climate.py b/homeassistant/components/plugwise/climate.py index 1063254299e..ff1325ffbf9 100644 --- a/homeassistant/components/plugwise/climate.py +++ b/homeassistant/components/plugwise/climate.py @@ -19,7 +19,6 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import ( COORDINATOR, @@ -30,6 +29,7 @@ from .const import ( SCHEDULE_OFF, SCHEDULE_ON, ) +from .coordinator import PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity HVAC_MODES_HEAT_ONLY = [HVAC_MODE_HEAT, HVAC_MODE_AUTO] @@ -88,7 +88,7 @@ class PwThermostat(PlugwiseEntity, ClimateEntity): def __init__( self, api: Smile, - coordinator: DataUpdateCoordinator, + coordinator: PlugwiseDataUpdateCoordinator, name: str, dev_id: str, loc_id: str, diff --git a/homeassistant/components/plugwise/coordinator.py b/homeassistant/components/plugwise/coordinator.py new file mode 100644 index 00000000000..ed6dad01f85 --- /dev/null +++ b/homeassistant/components/plugwise/coordinator.py @@ -0,0 +1,36 @@ +"""DataUpdateCoordinator for Plugwise.""" +from datetime import timedelta + +import async_timeout +from plugwise import Smile +from plugwise.exceptions import XMLDataMissingError + +from homeassistant.core import HomeAssistant +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed + +from .const import DEFAULT_SCAN_INTERVAL, DEFAULT_TIMEOUT, DOMAIN, LOGGER + + +class PlugwiseDataUpdateCoordinator(DataUpdateCoordinator[bool]): + """Class to manage fetching Plugwise data from single endpoint.""" + + def __init__(self, hass: HomeAssistant, api: Smile) -> None: + """Initialize the coordinator.""" + super().__init__( + hass, + LOGGER, + name=api.smile_name or DOMAIN, + update_interval=DEFAULT_SCAN_INTERVAL.get( + str(api.smile_type), timedelta(seconds=60) + ), + ) + self.api = api + + async def _async_update_data(self) -> bool: + """Fetch data from Plugwise.""" + try: + async with async_timeout.timeout(DEFAULT_TIMEOUT): + await self.api.full_update_device() + except XMLDataMissingError as err: + raise UpdateFailed("Smile update failed") from err + return True diff --git a/homeassistant/components/plugwise/entity.py b/homeassistant/components/plugwise/entity.py index 8a2526d4811..f33ba98235b 100644 --- a/homeassistant/components/plugwise/entity.py +++ b/homeassistant/components/plugwise/entity.py @@ -11,21 +11,23 @@ from homeassistant.const import ( ) from homeassistant.core import callback from homeassistant.helpers.entity import DeviceInfo -from homeassistant.helpers.update_coordinator import ( - CoordinatorEntity, - DataUpdateCoordinator, -) +from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN +from .coordinator import PlugwiseDataUpdateCoordinator -class PlugwiseEntity(CoordinatorEntity): +class PlugwiseEntity(CoordinatorEntity[bool]): """Represent a PlugWise Entity.""" _model: str | None = None def __init__( - self, api: Smile, coordinator: DataUpdateCoordinator, name: str, dev_id: str + self, + api: Smile, + coordinator: PlugwiseDataUpdateCoordinator, + name: str, + dev_id: str, ) -> None: """Initialise the gateway.""" super().__init__(coordinator) diff --git a/homeassistant/components/plugwise/gateway.py b/homeassistant/components/plugwise/gateway.py index e851941cf27..d1d35e3134b 100644 --- a/homeassistant/components/plugwise/gateway.py +++ b/homeassistant/components/plugwise/gateway.py @@ -3,12 +3,7 @@ from __future__ import annotations import asyncio -import async_timeout -from plugwise.exceptions import ( - InvalidAuthentication, - PlugwiseException, - XMLDataMissingError, -) +from plugwise.exceptions import InvalidAuthentication, PlugwiseException from plugwise.smile import Smile from homeassistant.config_entries import ConfigEntry @@ -17,13 +12,10 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers import device_registry as dr from homeassistant.helpers.aiohttp_client import async_get_clientsession -from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import ( COORDINATOR, DEFAULT_PORT, - DEFAULT_SCAN_INTERVAL, - DEFAULT_TIMEOUT, DEFAULT_USERNAME, DOMAIN, GATEWAY, @@ -32,6 +24,7 @@ from .const import ( PW_TYPE, SENSOR_PLATFORMS, ) +from .coordinator import PlugwiseDataUpdateCoordinator async def async_setup_entry_gw(hass: HomeAssistant, entry: ConfigEntry) -> bool: @@ -63,22 +56,7 @@ async def async_setup_entry_gw(hass: HomeAssistant, entry: ConfigEntry) -> bool: if not connected: raise ConfigEntryNotReady("Unable to connect to Smile") - async def async_update_data(): - """Update data via API endpoint.""" - try: - async with async_timeout.timeout(DEFAULT_TIMEOUT): - await api.full_update_device() - return True - except XMLDataMissingError as err: - raise UpdateFailed("Smile update failed") from err - - coordinator = DataUpdateCoordinator( - hass, - LOGGER, - name=f"Smile {api.smile_name}", - update_method=async_update_data, - update_interval=DEFAULT_SCAN_INTERVAL[api.smile_type], - ) + coordinator = PlugwiseDataUpdateCoordinator(hass, api) await coordinator.async_config_entry_first_refresh() api.get_all_devices() diff --git a/homeassistant/components/plugwise/sensor.py b/homeassistant/components/plugwise/sensor.py index 9d3f2d780b1..3cba9f59651 100644 --- a/homeassistant/components/plugwise/sensor.py +++ b/homeassistant/components/plugwise/sensor.py @@ -20,7 +20,6 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import ( COOL_ICON, @@ -36,6 +35,7 @@ from .const import ( SENSOR_MAP_UOM, UNIT_LUMEN, ) +from .coordinator import PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity ATTR_TEMPERATURE = [ @@ -303,7 +303,7 @@ class SmileSensor(PlugwiseEntity, SensorEntity): def __init__( self, api: Smile, - coordinator: DataUpdateCoordinator, + coordinator: PlugwiseDataUpdateCoordinator, name: str, dev_id: str, sensor: str, @@ -329,7 +329,7 @@ class PwThermostatSensor(SmileSensor): def __init__( self, api: Smile, - coordinator: DataUpdateCoordinator, + coordinator: PlugwiseDataUpdateCoordinator, name: str, dev_id: str, sensor: str, @@ -364,7 +364,7 @@ class PwAuxDeviceSensor(SmileSensor): def __init__( self, api: Smile, - coordinator: DataUpdateCoordinator, + coordinator: PlugwiseDataUpdateCoordinator, name: str, dev_id: str, sensor: str, @@ -406,7 +406,7 @@ class PwPowerSensor(SmileSensor): def __init__( self, api: Smile, - coordinator: DataUpdateCoordinator, + coordinator: PlugwiseDataUpdateCoordinator, name: str, dev_id: str, sensor: str, diff --git a/homeassistant/components/plugwise/switch.py b/homeassistant/components/plugwise/switch.py index f9ae7f62e18..e5436389fca 100644 --- a/homeassistant/components/plugwise/switch.py +++ b/homeassistant/components/plugwise/switch.py @@ -10,9 +10,9 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import COORDINATOR, DOMAIN, LOGGER, SWITCH_ICON +from .coordinator import PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity @@ -60,7 +60,7 @@ class GwSwitch(PlugwiseEntity, SwitchEntity): def __init__( self, api: Smile, - coordinator: DataUpdateCoordinator, + coordinator: PlugwiseDataUpdateCoordinator, name: str, dev_id: str, members: list[str] | None,