mirror of
https://github.com/home-assistant/core.git
synced 2026-09-26 01:11:51 -04:00
Use runtime_data in vallox integration (#168604)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
0c294b342c
commit
d96b626497
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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)]
|
||||
)
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user