mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 14:17:45 +00:00
Add support for multiple devices linked to a Viessmann account (#96044)
* care about all devices * use first device for diagnostics * update constants * handle multiple devices * handle multiple devices * handle multiple devices * handle multiple devices * handle multiple devices * code style * code style * code style * code style * code style * remove unused import * remove unused import * use has_entity_name and add serial to device name * use has_entity_name and add serial to device name * use has_entity_name and add serial to device name * use has_entity_name and add serial to device name * use has_entity_name and add serial to device name * remove unused constant * Update const.py * Update binary_sensor.py * change format * change format * fix line duplication * fix line duplication * change format * fix typo * use serial in device name if multiple devices are found * add common base class * use base class * Update __init__.py * Update __init__.py * Update __init__.py * Update sensor.py * Update binary_sensor.py * correct import * use base class * fix cdestyle findings * fix pylint findings * fix mypy findings * fix codestyle finidings * move has_entity_name to base class * Revert "fix mypy findings" This reverts commit 2d78801a69ec13670e0ef47354daf54b383eb595. * fix type issue * move multiple device handling * fix import * remove special handling for device name * extract api getter * Update __init__.py * Update __init__.py * Update entity.py * Update button.py * Update binary_sensor.py * Update climate.py * Update sensor.py * Update water_heater.py * Apply suggestions from code review Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update __init__.py * fix mypy & black * move get_device to utils * rename const * Apply suggestions from code review Co-authored-by: Robert Resch <robert@resch.dev> * store device in config entry * extract types * fix diagnostics * handle new platform * handle api rate limit * add types * add types * rename * add types * ignore gateways for now * Update .coveragerc * adjust types * fix merge issues * rename * Update types.py * fix type * add test method * simplify * ignore unused devices * Apply suggestions from code review Co-authored-by: Robert Resch <robert@resch.dev> * fix findings * handle unsupported devices * Apply suggestions from code review Co-authored-by: Robert Resch <robert@resch.dev> * Update types.py * fix format * adjust variable naming * Update conftest.py * Update conftest.py * remove kw_only * Apply suggestions from code review * Update __init__.py * Update binary_sensor.py * Update button.py * Update climate.py * Update const.py * Update diagnostics.py * Update number.py * Update sensor.py * Update types.py * Update water_heater.py * fix comment * Apply suggestions from code review Co-authored-by: Erik Montnemery <erik@montnemery.com> --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
parent
fd0f093299
commit
47cbe8f00c
@ -1535,6 +1535,7 @@ omit =
|
|||||||
homeassistant/components/vicare/entity.py
|
homeassistant/components/vicare/entity.py
|
||||||
homeassistant/components/vicare/number.py
|
homeassistant/components/vicare/number.py
|
||||||
homeassistant/components/vicare/sensor.py
|
homeassistant/components/vicare/sensor.py
|
||||||
|
homeassistant/components/vicare/types.py
|
||||||
homeassistant/components/vicare/utils.py
|
homeassistant/components/vicare/utils.py
|
||||||
homeassistant/components/vicare/water_heater.py
|
homeassistant/components/vicare/water_heater.py
|
||||||
homeassistant/components/vilfo/__init__.py
|
homeassistant/components/vilfo/__init__.py
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
"""The ViCare integration."""
|
"""The ViCare integration."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Callable, Mapping
|
from collections.abc import Mapping
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from dataclasses import dataclass
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from PyViCare.PyViCare import PyViCare
|
from PyViCare.PyViCare import PyViCare
|
||||||
from PyViCare.PyViCareDevice import Device
|
|
||||||
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||||
from PyViCare.PyViCareUtils import (
|
from PyViCare.PyViCareUtils import (
|
||||||
PyViCareInvalidConfigurationError,
|
PyViCareInvalidConfigurationError,
|
||||||
@ -22,36 +20,14 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.exceptions import ConfigEntryAuthFailed
|
from homeassistant.exceptions import ConfigEntryAuthFailed
|
||||||
from homeassistant.helpers.storage import STORAGE_DIR
|
from homeassistant.helpers.storage import STORAGE_DIR
|
||||||
|
|
||||||
from .const import (
|
from .const import DEFAULT_CACHE_DURATION, DEVICE_LIST, DOMAIN, PLATFORMS
|
||||||
CONF_HEATING_TYPE,
|
from .types import ViCareDevice
|
||||||
DEFAULT_SCAN_INTERVAL,
|
from .utils import get_device
|
||||||
DOMAIN,
|
|
||||||
HEATING_TYPE_TO_CREATOR_METHOD,
|
|
||||||
PLATFORMS,
|
|
||||||
VICARE_API,
|
|
||||||
VICARE_DEVICE_CONFIG,
|
|
||||||
VICARE_DEVICE_CONFIG_LIST,
|
|
||||||
HeatingType,
|
|
||||||
)
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
_TOKEN_FILENAME = "vicare_token.save"
|
_TOKEN_FILENAME = "vicare_token.save"
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class ViCareRequiredKeysMixin:
|
|
||||||
"""Mixin for required keys."""
|
|
||||||
|
|
||||||
value_getter: Callable[[Device], Any]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class ViCareRequiredKeysMixinWithSet(ViCareRequiredKeysMixin):
|
|
||||||
"""Mixin for required keys with setter."""
|
|
||||||
|
|
||||||
value_setter: Callable[[Device], bool]
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up from config entry."""
|
"""Set up from config entry."""
|
||||||
_LOGGER.debug("Setting up ViCare component")
|
_LOGGER.debug("Setting up ViCare component")
|
||||||
@ -69,10 +45,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def vicare_login(hass: HomeAssistant, entry_data: Mapping[str, Any]) -> PyViCare:
|
def vicare_login(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry_data: Mapping[str, Any],
|
||||||
|
cache_duration=DEFAULT_CACHE_DURATION,
|
||||||
|
) -> PyViCare:
|
||||||
"""Login via PyVicare API."""
|
"""Login via PyVicare API."""
|
||||||
vicare_api = PyViCare()
|
vicare_api = PyViCare()
|
||||||
vicare_api.setCacheDuration(DEFAULT_SCAN_INTERVAL)
|
vicare_api.setCacheDuration(cache_duration)
|
||||||
vicare_api.initWithCredentials(
|
vicare_api.initWithCredentials(
|
||||||
entry_data[CONF_USERNAME],
|
entry_data[CONF_USERNAME],
|
||||||
entry_data[CONF_PASSWORD],
|
entry_data[CONF_PASSWORD],
|
||||||
@ -87,20 +67,25 @@ def setup_vicare_api(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
|||||||
vicare_api = vicare_login(hass, entry.data)
|
vicare_api = vicare_login(hass, entry.data)
|
||||||
|
|
||||||
device_config_list = get_supported_devices(vicare_api.devices)
|
device_config_list = get_supported_devices(vicare_api.devices)
|
||||||
|
if (number_of_devices := len(device_config_list)) > 1:
|
||||||
|
cache_duration = DEFAULT_CACHE_DURATION * number_of_devices
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Found %s devices, adjusting cache duration to %s",
|
||||||
|
number_of_devices,
|
||||||
|
cache_duration,
|
||||||
|
)
|
||||||
|
vicare_api = vicare_login(hass, entry.data, cache_duration)
|
||||||
|
device_config_list = get_supported_devices(vicare_api.devices)
|
||||||
|
|
||||||
for device in device_config_list:
|
for device in device_config_list:
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Found device: %s (online: %s)", device.getModel(), str(device.isOnline())
|
"Found device: %s (online: %s)", device.getModel(), str(device.isOnline())
|
||||||
)
|
)
|
||||||
|
|
||||||
# Currently we only support a single device
|
hass.data[DOMAIN][entry.entry_id][DEVICE_LIST] = [
|
||||||
device = device_config_list[0]
|
ViCareDevice(config=device_config, api=get_device(entry, device_config))
|
||||||
hass.data[DOMAIN][entry.entry_id][VICARE_DEVICE_CONFIG_LIST] = device_config_list
|
for device_config in device_config_list
|
||||||
hass.data[DOMAIN][entry.entry_id][VICARE_DEVICE_CONFIG] = device
|
]
|
||||||
hass.data[DOMAIN][entry.entry_id][VICARE_API] = getattr(
|
|
||||||
device,
|
|
||||||
HEATING_TYPE_TO_CREATOR_METHOD[HeatingType(entry.data[CONF_HEATING_TYPE])],
|
|
||||||
)()
|
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
|
@ -27,9 +27,9 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import ViCareRequiredKeysMixin
|
from .const import DEVICE_LIST, DOMAIN
|
||||||
from .const import DOMAIN, VICARE_API, VICARE_DEVICE_CONFIG
|
|
||||||
from .entity import ViCareEntity
|
from .entity import ViCareEntity
|
||||||
|
from .types import ViCareDevice, ViCareRequiredKeysMixin
|
||||||
from .utils import get_burners, get_circuits, get_compressors, is_supported
|
from .utils import get_burners, get_circuits, get_compressors, is_supported
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -111,27 +111,26 @@ GLOBAL_SENSORS: tuple[ViCareBinarySensorEntityDescription, ...] = (
|
|||||||
|
|
||||||
|
|
||||||
def _build_entities(
|
def _build_entities(
|
||||||
device: PyViCareDevice,
|
device_list: list[ViCareDevice],
|
||||||
device_config: PyViCareDeviceConfig,
|
|
||||||
) -> list[ViCareBinarySensor]:
|
) -> list[ViCareBinarySensor]:
|
||||||
"""Create ViCare binary sensor entities for a device."""
|
"""Create ViCare binary sensor entities for a device."""
|
||||||
|
|
||||||
entities: list[ViCareBinarySensor] = _build_entities_for_device(
|
entities: list[ViCareBinarySensor] = []
|
||||||
device, device_config
|
for device in device_list:
|
||||||
)
|
entities.extend(_build_entities_for_device(device.api, device.config))
|
||||||
entities.extend(
|
entities.extend(
|
||||||
_build_entities_for_component(
|
_build_entities_for_component(
|
||||||
get_circuits(device), device_config, CIRCUIT_SENSORS
|
get_circuits(device.api), device.config, CIRCUIT_SENSORS
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
entities.extend(
|
entities.extend(
|
||||||
_build_entities_for_component(
|
_build_entities_for_component(
|
||||||
get_burners(device), device_config, BURNER_SENSORS
|
get_burners(device.api), device.config, BURNER_SENSORS
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
entities.extend(
|
entities.extend(
|
||||||
_build_entities_for_component(
|
_build_entities_for_component(
|
||||||
get_compressors(device), device_config, COMPRESSOR_SENSORS
|
get_compressors(device.api), device.config, COMPRESSOR_SENSORS
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return entities
|
return entities
|
||||||
@ -179,14 +178,12 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the ViCare binary sensor devices."""
|
"""Create the ViCare binary sensor devices."""
|
||||||
api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
|
device_list = hass.data[DOMAIN][config_entry.entry_id][DEVICE_LIST]
|
||||||
device_config = hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG]
|
|
||||||
|
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
_build_entities,
|
_build_entities,
|
||||||
api,
|
device_list,
|
||||||
device_config,
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@ from homeassistant.const import EntityCategory
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import ViCareRequiredKeysMixinWithSet
|
from .const import DEVICE_LIST, DOMAIN
|
||||||
from .const import DOMAIN, VICARE_API, VICARE_DEVICE_CONFIG
|
|
||||||
from .entity import ViCareEntity
|
from .entity import ViCareEntity
|
||||||
|
from .types import ViCareDevice, ViCareRequiredKeysMixinWithSet
|
||||||
from .utils import is_supported
|
from .utils import is_supported
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -48,19 +48,19 @@ BUTTON_DESCRIPTIONS: tuple[ViCareButtonEntityDescription, ...] = (
|
|||||||
|
|
||||||
|
|
||||||
def _build_entities(
|
def _build_entities(
|
||||||
api: PyViCareDevice,
|
device_list: list[ViCareDevice],
|
||||||
device_config: PyViCareDeviceConfig,
|
|
||||||
) -> list[ViCareButton]:
|
) -> list[ViCareButton]:
|
||||||
"""Create ViCare button entities for a device."""
|
"""Create ViCare button entities for a device."""
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ViCareButton(
|
ViCareButton(
|
||||||
api,
|
device.api,
|
||||||
device_config,
|
device.config,
|
||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
|
for device in device_list
|
||||||
for description in BUTTON_DESCRIPTIONS
|
for description in BUTTON_DESCRIPTIONS
|
||||||
if is_supported(description.key, description, api)
|
if is_supported(description.key, description, device.api)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -70,14 +70,12 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the ViCare button entities."""
|
"""Create the ViCare button entities."""
|
||||||
api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
|
device_list = hass.data[DOMAIN][config_entry.entry_id][DEVICE_LIST]
|
||||||
device_config = hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG]
|
|
||||||
|
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
_build_entities,
|
_build_entities,
|
||||||
api,
|
device_list,
|
||||||
device_config,
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,8 +40,9 @@ from homeassistant.helpers import entity_platform
|
|||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from .const import DOMAIN, VICARE_API, VICARE_DEVICE_CONFIG
|
from .const import DEVICE_LIST, DOMAIN
|
||||||
from .entity import ViCareEntity
|
from .entity import ViCareEntity
|
||||||
|
from .types import ViCareDevice
|
||||||
from .utils import get_burners, get_circuits, get_compressors
|
from .utils import get_burners, get_circuits, get_compressors
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -99,18 +100,18 @@ HA_TO_VICARE_PRESET_HEATING = {
|
|||||||
|
|
||||||
|
|
||||||
def _build_entities(
|
def _build_entities(
|
||||||
api: PyViCareDevice,
|
device_list: list[ViCareDevice],
|
||||||
device_config: PyViCareDeviceConfig,
|
|
||||||
) -> list[ViCareClimate]:
|
) -> list[ViCareClimate]:
|
||||||
"""Create ViCare climate entities for a device."""
|
"""Create ViCare climate entities for a device."""
|
||||||
return [
|
return [
|
||||||
ViCareClimate(
|
ViCareClimate(
|
||||||
api,
|
device.api,
|
||||||
circuit,
|
circuit,
|
||||||
device_config,
|
device.config,
|
||||||
"heating",
|
"heating",
|
||||||
)
|
)
|
||||||
for circuit in get_circuits(api)
|
for device in device_list
|
||||||
|
for circuit in get_circuits(device.api)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -120,8 +121,6 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the ViCare climate platform."""
|
"""Set up the ViCare climate platform."""
|
||||||
api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
|
|
||||||
device_config = hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG]
|
|
||||||
|
|
||||||
platform = entity_platform.async_get_current_platform()
|
platform = entity_platform.async_get_current_platform()
|
||||||
|
|
||||||
@ -131,11 +130,12 @@ async def async_setup_entry(
|
|||||||
"set_vicare_mode",
|
"set_vicare_mode",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
device_list = hass.data[DOMAIN][config_entry.entry_id][DEVICE_LIST]
|
||||||
|
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
_build_entities,
|
_build_entities,
|
||||||
api,
|
device_list,
|
||||||
device_config,
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -14,15 +14,13 @@ PLATFORMS = [
|
|||||||
Platform.WATER_HEATER,
|
Platform.WATER_HEATER,
|
||||||
]
|
]
|
||||||
|
|
||||||
VICARE_DEVICE_CONFIG = "device_conf"
|
DEVICE_LIST = "device_list"
|
||||||
VICARE_DEVICE_CONFIG_LIST = "device_config_list"
|
|
||||||
VICARE_API = "api"
|
|
||||||
VICARE_NAME = "ViCare"
|
VICARE_NAME = "ViCare"
|
||||||
|
|
||||||
CONF_CIRCUIT = "circuit"
|
CONF_CIRCUIT = "circuit"
|
||||||
CONF_HEATING_TYPE = "heating_type"
|
CONF_HEATING_TYPE = "heating_type"
|
||||||
|
|
||||||
DEFAULT_SCAN_INTERVAL = 60
|
DEFAULT_CACHE_DURATION = 60
|
||||||
|
|
||||||
VICARE_CUBIC_METER = "cubicMeter"
|
VICARE_CUBIC_METER = "cubicMeter"
|
||||||
VICARE_KWH = "kilowattHour"
|
VICARE_KWH = "kilowattHour"
|
||||||
|
@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.const import CONF_CLIENT_ID, CONF_PASSWORD, CONF_USERNAME
|
from homeassistant.const import CONF_CLIENT_ID, CONF_PASSWORD, CONF_USERNAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .const import DOMAIN, VICARE_DEVICE_CONFIG_LIST
|
from .const import DEVICE_LIST, DOMAIN
|
||||||
|
|
||||||
TO_REDACT = {CONF_CLIENT_ID, CONF_PASSWORD, CONF_USERNAME}
|
TO_REDACT = {CONF_CLIENT_ID, CONF_PASSWORD, CONF_USERNAME}
|
||||||
|
|
||||||
@ -18,10 +18,11 @@ async def async_get_config_entry_diagnostics(
|
|||||||
hass: HomeAssistant, entry: ConfigEntry
|
hass: HomeAssistant, entry: ConfigEntry
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
"""Return diagnostics for a config entry."""
|
"""Return diagnostics for a config entry."""
|
||||||
# Currently we only support a single device
|
|
||||||
data = []
|
data = []
|
||||||
for device in hass.data[DOMAIN][entry.entry_id][VICARE_DEVICE_CONFIG_LIST]:
|
for device in hass.data[DOMAIN][entry.entry_id][DEVICE_LIST]:
|
||||||
data.append(json.loads(await hass.async_add_executor_job(device.dump_secure)))
|
data.append(
|
||||||
|
json.loads(await hass.async_add_executor_job(device.config.dump_secure))
|
||||||
|
)
|
||||||
return {
|
return {
|
||||||
"entry": async_redact_data(entry.as_dict(), TO_REDACT),
|
"entry": async_redact_data(entry.as_dict(), TO_REDACT),
|
||||||
"data": data,
|
"data": data,
|
||||||
|
@ -29,9 +29,9 @@ from homeassistant.const import EntityCategory, UnitOfTemperature
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import ViCareRequiredKeysMixin
|
from .const import DEVICE_LIST, DOMAIN
|
||||||
from .const import DOMAIN, VICARE_API, VICARE_DEVICE_CONFIG
|
|
||||||
from .entity import ViCareEntity
|
from .entity import ViCareEntity
|
||||||
|
from .types import ViCareDevice, ViCareRequiredKeysMixin
|
||||||
from .utils import get_circuits, is_supported
|
from .utils import get_circuits, is_supported
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -123,18 +123,18 @@ CIRCUIT_ENTITY_DESCRIPTIONS: tuple[ViCareNumberEntityDescription, ...] = (
|
|||||||
|
|
||||||
|
|
||||||
def _build_entities(
|
def _build_entities(
|
||||||
api: PyViCareDevice,
|
device_list: list[ViCareDevice],
|
||||||
device_config: PyViCareDeviceConfig,
|
|
||||||
) -> list[ViCareNumber]:
|
) -> list[ViCareNumber]:
|
||||||
"""Create ViCare number entities for a component."""
|
"""Create ViCare number entities for a device."""
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ViCareNumber(
|
ViCareNumber(
|
||||||
circuit,
|
circuit,
|
||||||
device_config,
|
device.config,
|
||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
for circuit in get_circuits(api)
|
for device in device_list
|
||||||
|
for circuit in get_circuits(device.api)
|
||||||
for description in CIRCUIT_ENTITY_DESCRIPTIONS
|
for description in CIRCUIT_ENTITY_DESCRIPTIONS
|
||||||
if is_supported(description.key, description, circuit)
|
if is_supported(description.key, description, circuit)
|
||||||
]
|
]
|
||||||
@ -146,14 +146,12 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the ViCare number devices."""
|
"""Create the ViCare number devices."""
|
||||||
api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
|
device_list = hass.data[DOMAIN][config_entry.entry_id][DEVICE_LIST]
|
||||||
device_config = hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG]
|
|
||||||
|
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
_build_entities,
|
_build_entities,
|
||||||
api,
|
device_list,
|
||||||
device_config,
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,16 +38,15 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import ViCareRequiredKeysMixin
|
|
||||||
from .const import (
|
from .const import (
|
||||||
|
DEVICE_LIST,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
VICARE_API,
|
|
||||||
VICARE_CUBIC_METER,
|
VICARE_CUBIC_METER,
|
||||||
VICARE_DEVICE_CONFIG,
|
|
||||||
VICARE_KWH,
|
VICARE_KWH,
|
||||||
VICARE_UNIT_TO_UNIT_OF_MEASUREMENT,
|
VICARE_UNIT_TO_UNIT_OF_MEASUREMENT,
|
||||||
)
|
)
|
||||||
from .entity import ViCareEntity
|
from .entity import ViCareEntity
|
||||||
|
from .types import ViCareDevice, ViCareRequiredKeysMixin
|
||||||
from .utils import get_burners, get_circuits, get_compressors, is_supported
|
from .utils import get_burners, get_circuits, get_compressors, is_supported
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -693,25 +692,26 @@ COMPRESSOR_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
|
|||||||
|
|
||||||
|
|
||||||
def _build_entities(
|
def _build_entities(
|
||||||
device: PyViCareDevice,
|
device_list: list[ViCareDevice],
|
||||||
device_config: PyViCareDeviceConfig,
|
|
||||||
) -> list[ViCareSensor]:
|
) -> list[ViCareSensor]:
|
||||||
"""Create ViCare sensor entities for a device."""
|
"""Create ViCare sensor entities for a device."""
|
||||||
|
|
||||||
entities: list[ViCareSensor] = _build_entities_for_device(device, device_config)
|
entities: list[ViCareSensor] = []
|
||||||
|
for device in device_list:
|
||||||
|
entities.extend(_build_entities_for_device(device.api, device.config))
|
||||||
entities.extend(
|
entities.extend(
|
||||||
_build_entities_for_component(
|
_build_entities_for_component(
|
||||||
get_circuits(device), device_config, CIRCUIT_SENSORS
|
get_circuits(device.api), device.config, CIRCUIT_SENSORS
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
entities.extend(
|
entities.extend(
|
||||||
_build_entities_for_component(
|
_build_entities_for_component(
|
||||||
get_burners(device), device_config, BURNER_SENSORS
|
get_burners(device.api), device.config, BURNER_SENSORS
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
entities.extend(
|
entities.extend(
|
||||||
_build_entities_for_component(
|
_build_entities_for_component(
|
||||||
get_compressors(device), device_config, COMPRESSOR_SENSORS
|
get_compressors(device.api), device.config, COMPRESSOR_SENSORS
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return entities
|
return entities
|
||||||
@ -759,16 +759,12 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the ViCare sensor devices."""
|
"""Create the ViCare sensor devices."""
|
||||||
api: PyViCareDevice = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
|
device_list = hass.data[DOMAIN][config_entry.entry_id][DEVICE_LIST]
|
||||||
device_config: PyViCareDeviceConfig = hass.data[DOMAIN][config_entry.entry_id][
|
|
||||||
VICARE_DEVICE_CONFIG
|
|
||||||
]
|
|
||||||
|
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
_build_entities,
|
_build_entities,
|
||||||
api,
|
device_list,
|
||||||
device_config,
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
29
homeassistant/components/vicare/types.py
Normal file
29
homeassistant/components/vicare/types.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
"""Types for the ViCare integration."""
|
||||||
|
from collections.abc import Callable
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
||||||
|
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class ViCareDevice:
|
||||||
|
"""Dataclass holding the device api and config."""
|
||||||
|
|
||||||
|
config: PyViCareDeviceConfig
|
||||||
|
api: PyViCareDevice
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class ViCareRequiredKeysMixin:
|
||||||
|
"""Mixin for required keys."""
|
||||||
|
|
||||||
|
value_getter: Callable[[PyViCareDevice], Any]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class ViCareRequiredKeysMixinWithSet(ViCareRequiredKeysMixin):
|
||||||
|
"""Mixin for required keys with setter."""
|
||||||
|
|
||||||
|
value_setter: Callable[[PyViCareDevice], bool]
|
@ -2,16 +2,30 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
||||||
|
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||||
from PyViCare.PyViCareHeatingDevice import (
|
from PyViCare.PyViCareHeatingDevice import (
|
||||||
HeatingDeviceWithComponent as PyViCareHeatingDeviceComponent,
|
HeatingDeviceWithComponent as PyViCareHeatingDeviceComponent,
|
||||||
)
|
)
|
||||||
from PyViCare.PyViCareUtils import PyViCareNotSupportedFeatureError
|
from PyViCare.PyViCareUtils import PyViCareNotSupportedFeatureError
|
||||||
|
|
||||||
from . import ViCareRequiredKeysMixin
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
|
||||||
|
from .const import CONF_HEATING_TYPE, HEATING_TYPE_TO_CREATOR_METHOD, HeatingType
|
||||||
|
from .types import ViCareRequiredKeysMixin
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def get_device(
|
||||||
|
entry: ConfigEntry, device_config: PyViCareDeviceConfig
|
||||||
|
) -> PyViCareDevice:
|
||||||
|
"""Get device for device config."""
|
||||||
|
return getattr(
|
||||||
|
device_config,
|
||||||
|
HEATING_TYPE_TO_CREATOR_METHOD[HeatingType(entry.data[CONF_HEATING_TYPE])],
|
||||||
|
)()
|
||||||
|
|
||||||
|
|
||||||
def is_supported(
|
def is_supported(
|
||||||
name: str,
|
name: str,
|
||||||
entity_description: ViCareRequiredKeysMixin,
|
entity_description: ViCareRequiredKeysMixin,
|
||||||
|
@ -24,8 +24,9 @@ from homeassistant.const import ATTR_TEMPERATURE, PRECISION_TENTHS, UnitOfTemper
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from .const import DOMAIN, VICARE_API, VICARE_DEVICE_CONFIG
|
from .const import DEVICE_LIST, DOMAIN
|
||||||
from .entity import ViCareEntity
|
from .entity import ViCareEntity
|
||||||
|
from .types import ViCareDevice
|
||||||
from .utils import get_circuits
|
from .utils import get_circuits
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -61,18 +62,19 @@ HA_TO_VICARE_HVAC_DHW = {
|
|||||||
|
|
||||||
|
|
||||||
def _build_entities(
|
def _build_entities(
|
||||||
api: PyViCareDevice,
|
device_list: list[ViCareDevice],
|
||||||
device_config: PyViCareDeviceConfig,
|
|
||||||
) -> list[ViCareWater]:
|
) -> list[ViCareWater]:
|
||||||
"""Create ViCare domestic hot water entities for a device."""
|
"""Create ViCare domestic hot water entities for a device."""
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ViCareWater(
|
ViCareWater(
|
||||||
api,
|
device.api,
|
||||||
circuit,
|
circuit,
|
||||||
device_config,
|
device.config,
|
||||||
"domestic_hot_water",
|
"domestic_hot_water",
|
||||||
)
|
)
|
||||||
for circuit in get_circuits(api)
|
for device in device_list
|
||||||
|
for circuit in get_circuits(device.api)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -82,14 +84,12 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the ViCare water heater platform."""
|
"""Set up the ViCare water heater platform."""
|
||||||
api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
|
device_list = hass.data[DOMAIN][config_entry.entry_id][DEVICE_LIST]
|
||||||
device_config = hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG]
|
|
||||||
|
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
await hass.async_add_executor_job(
|
await hass.async_add_executor_job(
|
||||||
_build_entities,
|
_build_entities,
|
||||||
api,
|
device_list,
|
||||||
device_config,
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user