diff --git a/homeassistant/components/vallox/__init__.py b/homeassistant/components/vallox/__init__.py index a233138deeff..f3e65fa89256 100644 --- a/homeassistant/components/vallox/__init__.py +++ b/homeassistant/components/vallox/__init__.py @@ -7,14 +7,13 @@ import ipaddress from vallox_websocket_api import Vallox import voluptuous as vol -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_NAME, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv from homeassistant.helpers.typing import ConfigType from .const import DEFAULT_NAME, DOMAIN -from .coordinator import ValloxDataUpdateCoordinator +from .coordinator import ValloxConfigEntry, ValloxDataUpdateCoordinator from .services import async_setup_services CONFIG_SCHEMA = vol.Schema( @@ -48,10 +47,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: return True -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: ValloxConfigEntry) -> bool: """Set up the client and boot the platforms.""" host = entry.data[CONF_HOST] - name = entry.data[CONF_NAME] client = Vallox(host) @@ -59,20 +57,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: await coordinator.async_config_entry_first_refresh() - hass.data.setdefault(DOMAIN, {})[entry.entry_id] = { - "client": client, - "coordinator": coordinator, - "name": name, - } + entry.runtime_data = coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: ValloxConfigEntry) -> bool: """Unload a config entry.""" - if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): - hass.data[DOMAIN].pop(entry.entry_id) - - return unload_ok + return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/vallox/binary_sensor.py b/homeassistant/components/vallox/binary_sensor.py index a205dd2039ec..d7268a3806fa 100644 --- a/homeassistant/components/vallox/binary_sensor.py +++ b/homeassistant/components/vallox/binary_sensor.py @@ -8,13 +8,11 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, BinarySensorEntityDescription, ) -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import EntityCategory +from homeassistant.const import CONF_NAME, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import DOMAIN -from .coordinator import ValloxDataUpdateCoordinator +from .coordinator import ValloxConfigEntry, ValloxDataUpdateCoordinator from .entity import ValloxEntity @@ -61,14 +59,11 @@ BINARY_SENSOR_ENTITIES: tuple[ValloxBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, + entry: ValloxConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" - - data = hass.data[DOMAIN][entry.entry_id] - async_add_entities( - ValloxBinarySensorEntity(data["name"], data["coordinator"], description) + ValloxBinarySensorEntity(entry.data[CONF_NAME], entry.runtime_data, description) for description in BINARY_SENSOR_ENTITIES ) diff --git a/homeassistant/components/vallox/coordinator.py b/homeassistant/components/vallox/coordinator.py index 2fe7fa533db3..ffaae9b1e00e 100644 --- a/homeassistant/components/vallox/coordinator.py +++ b/homeassistant/components/vallox/coordinator.py @@ -15,16 +15,18 @@ from .const import STATE_SCAN_INTERVAL _LOGGER = logging.getLogger(__name__) +type ValloxConfigEntry = ConfigEntry[ValloxDataUpdateCoordinator] + class ValloxDataUpdateCoordinator(DataUpdateCoordinator[MetricData]): """The DataUpdateCoordinator for Vallox.""" - config_entry: ConfigEntry + config_entry: ValloxConfigEntry def __init__( self, hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: ValloxConfigEntry, client: Vallox, ) -> None: """Initialize Vallox data coordinator.""" diff --git a/homeassistant/components/vallox/date.py b/homeassistant/components/vallox/date.py index da2906c02c2c..96b38298d877 100644 --- a/homeassistant/components/vallox/date.py +++ b/homeassistant/components/vallox/date.py @@ -4,16 +4,12 @@ from __future__ import annotations from datetime import date -from vallox_websocket_api import Vallox - from homeassistant.components.date import DateEntity -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import EntityCategory +from homeassistant.const import CONF_NAME, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import DOMAIN -from .coordinator import ValloxDataUpdateCoordinator +from .coordinator import ValloxConfigEntry, ValloxDataUpdateCoordinator from .entity import ValloxEntity @@ -27,13 +23,11 @@ class ValloxFilterChangeDateEntity(ValloxEntity, DateEntity): self, name: str, coordinator: ValloxDataUpdateCoordinator, - client: Vallox, ) -> None: """Initialize the Vallox date.""" super().__init__(name, coordinator) self._attr_unique_id = f"{self._device_uuid}-filter_change_date" - self._client = client @property def native_value(self) -> date | None: @@ -44,23 +38,18 @@ class ValloxFilterChangeDateEntity(ValloxEntity, DateEntity): async def async_set_value(self, value: date) -> None: """Change the date.""" - await self._client.set_filter_change_date(value) + await self.coordinator.client.set_filter_change_date(value) await self.coordinator.async_request_refresh() async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, + entry: ValloxConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Vallox filter change date entity.""" - - data = hass.data[DOMAIN][entry.entry_id] + coordinator = entry.runtime_data async_add_entities( - [ - ValloxFilterChangeDateEntity( - data["name"], data["coordinator"], data["client"] - ) - ] + [ValloxFilterChangeDateEntity(entry.data[CONF_NAME], coordinator)] ) diff --git a/homeassistant/components/vallox/fan.py b/homeassistant/components/vallox/fan.py index 8519b4cb913d..6d94e2ed1a33 100644 --- a/homeassistant/components/vallox/fan.py +++ b/homeassistant/components/vallox/fan.py @@ -5,17 +5,16 @@ from __future__ import annotations from collections.abc import Mapping from typing import Any, NamedTuple -from vallox_websocket_api import Vallox, ValloxApiException, ValloxInvalidInputException +from vallox_websocket_api import ValloxApiException, ValloxInvalidInputException from homeassistant.components.fan import FanEntity, FanEntityFeature -from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType from .const import ( - DOMAIN, METRIC_KEY_MODE, METRIC_KEY_PROFILE_FAN_SPEED_AWAY, METRIC_KEY_PROFILE_FAN_SPEED_BOOST, @@ -25,7 +24,7 @@ from .const import ( PRESET_MODE_TO_VALLOX_PROFILE, VALLOX_PROFILE_TO_PRESET_MODE, ) -from .coordinator import ValloxDataUpdateCoordinator +from .coordinator import ValloxConfigEntry, ValloxDataUpdateCoordinator from .entity import ValloxEntity @@ -58,19 +57,13 @@ def _convert_to_int(value: StateType) -> int | None: async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, + entry: ValloxConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the fan device.""" - data = hass.data[DOMAIN][entry.entry_id] + coordinator = entry.runtime_data - client = data["client"] - - device = ValloxFanEntity( - data["name"], - client, - data["coordinator"], - ) + device = ValloxFanEntity(entry.data[CONF_NAME], coordinator) async_add_entities([device]) @@ -89,14 +82,11 @@ class ValloxFanEntity(ValloxEntity, FanEntity): def __init__( self, name: str, - client: Vallox, coordinator: ValloxDataUpdateCoordinator, ) -> None: """Initialize the fan.""" super().__init__(name, coordinator) - self._client = client - self._attr_unique_id = str(self._device_uuid) self._attr_preset_modes = list(PRESET_MODE_TO_VALLOX_PROFILE) @@ -188,7 +178,7 @@ class ValloxFanEntity(ValloxEntity, FanEntity): async def _async_set_power(self, mode: bool) -> bool: try: - await self._client.set_values( + await self.coordinator.client.set_values( {METRIC_KEY_MODE: MODE_ON if mode else MODE_OFF} ) except ValloxApiException as err: @@ -206,7 +196,7 @@ class ValloxFanEntity(ValloxEntity, FanEntity): try: profile = PRESET_MODE_TO_VALLOX_PROFILE[preset_mode] - await self._client.set_profile(profile) + await self.coordinator.client.set_profile(profile) except ValloxApiException as err: raise HomeAssistantError(f"Failed to set profile: {preset_mode}") from err @@ -227,7 +217,7 @@ class ValloxFanEntity(ValloxEntity, FanEntity): ) try: - await self._client.set_fan_speed(vallox_profile, percentage) + await self.coordinator.client.set_fan_speed(vallox_profile, percentage) except ValloxInvalidInputException as err: # This can happen if current profile does not support setting the fan speed. raise ValueError( diff --git a/homeassistant/components/vallox/number.py b/homeassistant/components/vallox/number.py index ce3b9c72a6d8..b879b9201714 100644 --- a/homeassistant/components/vallox/number.py +++ b/homeassistant/components/vallox/number.py @@ -4,20 +4,16 @@ from __future__ import annotations from dataclasses import dataclass -from vallox_websocket_api import Vallox - from homeassistant.components.number import ( NumberDeviceClass, NumberEntity, NumberEntityDescription, ) -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import EntityCategory, UnitOfTemperature +from homeassistant.const import CONF_NAME, EntityCategory, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import DOMAIN -from .coordinator import ValloxDataUpdateCoordinator +from .coordinator import ValloxConfigEntry, ValloxDataUpdateCoordinator from .entity import ValloxEntity @@ -32,7 +28,6 @@ class ValloxNumberEntity(ValloxEntity, NumberEntity): name: str, coordinator: ValloxDataUpdateCoordinator, description: ValloxNumberEntityDescription, - client: Vallox, ) -> None: """Initialize the Vallox number entity.""" super().__init__(name, coordinator) @@ -40,7 +35,6 @@ class ValloxNumberEntity(ValloxEntity, NumberEntity): self.entity_description = description self._attr_unique_id = f"{self._device_uuid}-{description.key}" - self._client = client @property def native_value(self) -> float | None: @@ -54,7 +48,7 @@ class ValloxNumberEntity(ValloxEntity, NumberEntity): async def async_set_native_value(self, value: float) -> None: """Update the current value.""" - await self._client.set_values( + await self.coordinator.client.set_values( {self.entity_description.metric_key: float(value)} ) await self.coordinator.async_request_refresh() @@ -103,15 +97,13 @@ NUMBER_ENTITIES: tuple[ValloxNumberEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, + entry: ValloxConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" - data = hass.data[DOMAIN][entry.entry_id] + coordinator = entry.runtime_data async_add_entities( - ValloxNumberEntity( - data["name"], data["coordinator"], description, data["client"] - ) + ValloxNumberEntity(entry.data[CONF_NAME], coordinator, description) for description in NUMBER_ENTITIES ) diff --git a/homeassistant/components/vallox/sensor.py b/homeassistant/components/vallox/sensor.py index e9194a8254c3..54f7ecd28105 100644 --- a/homeassistant/components/vallox/sensor.py +++ b/homeassistant/components/vallox/sensor.py @@ -11,9 +11,9 @@ from homeassistant.components.sensor import ( SensorEntityDescription, SensorStateClass, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONCENTRATION_PARTS_PER_MILLION, + CONF_NAME, PERCENTAGE, REVOLUTIONS_PER_MINUTE, EntityCategory, @@ -26,13 +26,12 @@ from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util from .const import ( - DOMAIN, METRIC_KEY_MODE, MODE_ON, VALLOX_CELL_STATE_TO_STR, VALLOX_PROFILE_TO_PRESET_MODE, ) -from .coordinator import ValloxDataUpdateCoordinator +from .coordinator import ValloxConfigEntry, ValloxDataUpdateCoordinator from .entity import ValloxEntity @@ -279,12 +278,12 @@ SENSOR_ENTITIES: tuple[ValloxSensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, + entry: ValloxConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the sensors.""" - name = hass.data[DOMAIN][entry.entry_id]["name"] - coordinator = hass.data[DOMAIN][entry.entry_id]["coordinator"] + name = entry.data[CONF_NAME] + coordinator = entry.runtime_data async_add_entities( description.entity_type(name, coordinator, description) diff --git a/homeassistant/components/vallox/services.py b/homeassistant/components/vallox/services.py index 2562d2501cec..2d6c3f4463ca 100644 --- a/homeassistant/components/vallox/services.py +++ b/homeassistant/components/vallox/services.py @@ -5,13 +5,13 @@ from __future__ import annotations from enum import StrEnum, auto import logging -from vallox_websocket_api import Profile, Vallox, ValloxApiException +from vallox_websocket_api import Profile, ValloxApiException import voluptuous as vol from homeassistant.core import HomeAssistant, ServiceCall, callback from .const import DOMAIN, I18N_KEY_TO_VALLOX_PROFILE -from .coordinator import ValloxDataUpdateCoordinator +from .coordinator import ValloxConfigEntry, ValloxDataUpdateCoordinator _LOGGER = logging.getLogger(__name__) @@ -47,16 +47,15 @@ SERVICE_SCHEMA_SET_PROFILE = vol.Schema( ) -def _get_client( +def _get_coordinator( hass: HomeAssistant, -) -> tuple[Vallox, ValloxDataUpdateCoordinator]: - """Return (client, coordinator) for Vallox config entry.""" - entries = hass.config_entries.async_loaded_entries(DOMAIN) +) -> ValloxDataUpdateCoordinator: + """Return the coordinator for the Vallox config entry.""" + entries: list[ValloxConfigEntry] = hass.config_entries.async_loaded_entries(DOMAIN) if len(entries) != 1: raise ValueError("Expected exactly one loaded Vallox config entry") - data = hass.data[DOMAIN][entries[0].entry_id] - return data["client"], data["coordinator"] + return entries[0].runtime_data async def _async_set_profile_fan_speed(call: ServiceCall, profile: Profile) -> None: @@ -64,9 +63,9 @@ async def _async_set_profile_fan_speed(call: ServiceCall, profile: Profile) -> N fan_speed: int = call.data[ATTR_PROFILE_FAN_SPEED] _LOGGER.debug("Setting %s fan speed to: %d%%", profile.name, fan_speed) - client, coordinator = _get_client(call.hass) + coordinator = _get_coordinator(call.hass) try: - await client.set_fan_speed(profile, fan_speed) + await coordinator.client.set_fan_speed(profile, fan_speed) except ValloxApiException as err: _LOGGER.error("Error setting fan speed for %s profile: %s", profile.name, err) else: @@ -94,9 +93,11 @@ async def _async_set_profile(call: ServiceCall) -> None: duration: int | None = call.data.get(ATTR_DURATION) _LOGGER.debug("Activating profile %s for %s min", profile_key, duration) - client, coordinator = _get_client(call.hass) + coordinator = _get_coordinator(call.hass) try: - await client.set_profile(I18N_KEY_TO_VALLOX_PROFILE[profile_key], duration) + await coordinator.client.set_profile( + I18N_KEY_TO_VALLOX_PROFILE[profile_key], duration + ) except ValloxApiException as err: _LOGGER.error( "Error setting profile %s for duration %s: %s", diff --git a/homeassistant/components/vallox/switch.py b/homeassistant/components/vallox/switch.py index 9386f914f58c..2a023f09a54b 100644 --- a/homeassistant/components/vallox/switch.py +++ b/homeassistant/components/vallox/switch.py @@ -5,16 +5,12 @@ from __future__ import annotations from dataclasses import dataclass from typing import Any -from vallox_websocket_api import Vallox - from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import EntityCategory +from homeassistant.const import CONF_NAME, EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import DOMAIN -from .coordinator import ValloxDataUpdateCoordinator +from .coordinator import ValloxConfigEntry, ValloxDataUpdateCoordinator from .entity import ValloxEntity @@ -29,7 +25,6 @@ class ValloxSwitchEntity(ValloxEntity, SwitchEntity): name: str, coordinator: ValloxDataUpdateCoordinator, description: ValloxSwitchEntityDescription, - client: Vallox, ) -> None: """Initialize the Vallox switch.""" super().__init__(name, coordinator) @@ -37,7 +32,6 @@ class ValloxSwitchEntity(ValloxEntity, SwitchEntity): self.entity_description = description self._attr_unique_id = f"{self._device_uuid}-{description.key}" - self._client = client @property def is_on(self) -> bool | None: @@ -59,7 +53,7 @@ class ValloxSwitchEntity(ValloxEntity, SwitchEntity): async def _set_value(self, value: bool) -> None: """Update the current value.""" metric_key = self.entity_description.metric_key - await self._client.set_values({metric_key: 1 if value else 0}) + await self.coordinator.client.set_values({metric_key: 1 if value else 0}) await self.coordinator.async_request_refresh() @@ -81,16 +75,13 @@ SWITCH_ENTITIES: tuple[ValloxSwitchEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, + entry: ValloxConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the switches.""" - - data = hass.data[DOMAIN][entry.entry_id] + coordinator = entry.runtime_data async_add_entities( - ValloxSwitchEntity( - data["name"], data["coordinator"], description, data["client"] - ) + ValloxSwitchEntity(entry.data[CONF_NAME], coordinator, description) for description in SWITCH_ENTITIES )