diff --git a/homeassistant/components/vicare/binary_sensor.py b/homeassistant/components/vicare/binary_sensor.py index f92f24d01ce..525099e7d4e 100644 --- a/homeassistant/components/vicare/binary_sensor.py +++ b/homeassistant/components/vicare/binary_sensor.py @@ -7,6 +7,9 @@ import logging from PyViCare.PyViCareDevice import Device as PyViCareDevice from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig +from PyViCare.PyViCareHeatingDevice import ( + HeatingDeviceWithComponent as PyViCareHeatingDeviceWithComponent, +) from PyViCare.PyViCareUtils import ( PyViCareInvalidDataError, PyViCareNotSupportedFeatureError, @@ -104,39 +107,67 @@ GLOBAL_SENSORS: tuple[ViCareBinarySensorEntityDescription, ...] = ( ) -def _build_entity( - vicare_api: PyViCareDevice, +def _build_entities( + device: PyViCareDevice, device_config: PyViCareDeviceConfig, - entity_description: ViCareBinarySensorEntityDescription, -): - """Create a ViCare binary sensor entity.""" - if is_supported(entity_description.key, entity_description, vicare_api): - return ViCareBinarySensor( - vicare_api, - device_config, - entity_description, +) -> list[ViCareBinarySensor]: + """Create ViCare binary sensor entities for a device.""" + + entities: list[ViCareBinarySensor] = _build_entities_for_device( + device, device_config + ) + entities.extend( + _build_entities_for_component( + get_circuits(device), device_config, CIRCUIT_SENSORS ) - return None + ) + entities.extend( + _build_entities_for_component( + get_burners(device), device_config, BURNER_SENSORS + ) + ) + entities.extend( + _build_entities_for_component( + get_compressors(device), device_config, COMPRESSOR_SENSORS + ) + ) + return entities -async def _entities_from_descriptions( - hass: HomeAssistant, - entities: list[ViCareBinarySensor], - sensor_descriptions: tuple[ViCareBinarySensorEntityDescription, ...], - iterables, - config_entry: ConfigEntry, -) -> None: - """Create entities from descriptions and list of burners/circuits.""" - for description in sensor_descriptions: - for current in iterables: - entity = await hass.async_add_executor_job( - _build_entity, - current, - hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG], - description, - ) - if entity: - entities.append(entity) +def _build_entities_for_device( + device: PyViCareDevice, + device_config: PyViCareDeviceConfig, +) -> list[ViCareBinarySensor]: + """Create device specific ViCare binary sensor entities.""" + + return [ + ViCareBinarySensor( + device, + device_config, + description, + ) + for description in GLOBAL_SENSORS + if is_supported(description.key, description, device) + ] + + +def _build_entities_for_component( + components: list[PyViCareHeatingDeviceWithComponent], + device_config: PyViCareDeviceConfig, + entity_descriptions: tuple[ViCareBinarySensorEntityDescription, ...], +) -> list[ViCareBinarySensor]: + """Create component specific ViCare binary sensor entities.""" + + return [ + ViCareBinarySensor( + component, + device_config, + description, + ) + for component in components + for description in entity_descriptions + if is_supported(description.key, description, component) + ] async def async_setup_entry( @@ -146,36 +177,16 @@ async def async_setup_entry( ) -> None: """Create the ViCare binary sensor devices.""" api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API] + device_config = hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG] - entities = [] - - for description in GLOBAL_SENSORS: - entity = await hass.async_add_executor_job( - _build_entity, + async_add_entities( + await hass.async_add_executor_job( + _build_entities, api, - hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG], - description, + device_config, ) - if entity: - entities.append(entity) - - circuits = await hass.async_add_executor_job(get_circuits, api) - await _entities_from_descriptions( - hass, entities, CIRCUIT_SENSORS, circuits, config_entry ) - burners = await hass.async_add_executor_job(get_burners, api) - await _entities_from_descriptions( - hass, entities, BURNER_SENSORS, burners, config_entry - ) - - compressors = await hass.async_add_executor_job(get_compressors, api) - await _entities_from_descriptions( - hass, entities, COMPRESSOR_SENSORS, compressors, config_entry - ) - - async_add_entities(entities) - class ViCareBinarySensor(ViCareEntity, BinarySensorEntity): """Representation of a ViCare sensor.""" diff --git a/homeassistant/components/vicare/button.py b/homeassistant/components/vicare/button.py index d0e50b5f772..374d98b3397 100644 --- a/homeassistant/components/vicare/button.py +++ b/homeassistant/components/vicare/button.py @@ -47,19 +47,21 @@ BUTTON_DESCRIPTIONS: tuple[ViCareButtonEntityDescription, ...] = ( ) -def _build_entity( - vicare_api: PyViCareDevice, +def _build_entities( + api: PyViCareDevice, device_config: PyViCareDeviceConfig, - entity_description: ViCareButtonEntityDescription, -): - """Create a ViCare button entity.""" - if is_supported(entity_description.key, entity_description, vicare_api): - return ViCareButton( - vicare_api, +) -> list[ViCareButton]: + """Create ViCare button entities for a device.""" + + return [ + ViCareButton( + api, device_config, - entity_description, + description, ) - return None + for description in BUTTON_DESCRIPTIONS + if is_supported(description.key, description, api) + ] async def async_setup_entry( @@ -69,20 +71,15 @@ async def async_setup_entry( ) -> None: """Create the ViCare button entities.""" api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API] + device_config = hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG] - entities = [] - - for description in BUTTON_DESCRIPTIONS: - entity = await hass.async_add_executor_job( - _build_entity, + async_add_entities( + await hass.async_add_executor_job( + _build_entities, api, - hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG], - description, + device_config, ) - if entity: - entities.append(entity) - - async_add_entities(entities) + ) class ViCareButton(ViCareEntity, ButtonEntity): diff --git a/homeassistant/components/vicare/climate.py b/homeassistant/components/vicare/climate.py index c1e04e1d1b2..c14f940ffe6 100644 --- a/homeassistant/components/vicare/climate.py +++ b/homeassistant/components/vicare/climate.py @@ -95,25 +95,30 @@ HA_TO_VICARE_PRESET_HEATING = { } +def _build_entities( + api: PyViCareDevice, + device_config: PyViCareDeviceConfig, +) -> list[ViCareClimate]: + """Create ViCare climate entities for a device.""" + return [ + ViCareClimate( + api, + circuit, + device_config, + "heating", + ) + for circuit in get_circuits(api) + ] + + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the ViCare climate platform.""" - entities = [] api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API] device_config = hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG] - circuits = await hass.async_add_executor_job(get_circuits, api) - - for circuit in circuits: - entity = ViCareClimate( - api, - circuit, - device_config, - "heating", - ) - entities.append(entity) platform = entity_platform.async_get_current_platform() @@ -123,7 +128,13 @@ async def async_setup_entry( "set_vicare_mode", ) - async_add_entities(entities) + async_add_entities( + await hass.async_add_executor_job( + _build_entities, + api, + device_config, + ) + ) class ViCareClimate(ViCareEntity, ClimateEntity): diff --git a/homeassistant/components/vicare/number.py b/homeassistant/components/vicare/number.py index f8abea13401..5511f2a5294 100644 --- a/homeassistant/components/vicare/number.py +++ b/homeassistant/components/vicare/number.py @@ -80,19 +80,22 @@ CIRCUIT_ENTITY_DESCRIPTIONS: tuple[ViCareNumberEntityDescription, ...] = ( ) -def _build_entity( - vicare_api: PyViCareHeatingDeviceComponent, +def _build_entities( + api: PyViCareDevice, device_config: PyViCareDeviceConfig, - entity_description: ViCareNumberEntityDescription, -) -> ViCareNumber | None: - """Create a ViCare number entity.""" - if is_supported(entity_description.key, entity_description, vicare_api): - return ViCareNumber( - vicare_api, +) -> list[ViCareNumber]: + """Create ViCare number entities for a component.""" + + return [ + ViCareNumber( + circuit, device_config, - entity_description, + description, ) - return None + for circuit in get_circuits(api) + for description in CIRCUIT_ENTITY_DESCRIPTIONS + if is_supported(description.key, description, circuit) + ] async def async_setup_entry( @@ -101,23 +104,16 @@ async def async_setup_entry( async_add_entities: AddEntitiesCallback, ) -> None: """Create the ViCare number devices.""" - entities: list[ViCareNumber] = [] api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API] device_config = hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG] - circuits = await hass.async_add_executor_job(get_circuits, api) - for circuit in circuits: - for description in CIRCUIT_ENTITY_DESCRIPTIONS: - entity = await hass.async_add_executor_job( - _build_entity, - circuit, - device_config, - description, - ) - if entity: - entities.append(entity) - - async_add_entities(entities) + async_add_entities( + await hass.async_add_executor_job( + _build_entities, + api, + device_config, + ) + ) class ViCareNumber(ViCareEntity, NumberEntity): diff --git a/homeassistant/components/vicare/sensor.py b/homeassistant/components/vicare/sensor.py index bfad8b107cb..875d8790c52 100644 --- a/homeassistant/components/vicare/sensor.py +++ b/homeassistant/components/vicare/sensor.py @@ -6,8 +6,11 @@ from contextlib import suppress from dataclasses import dataclass import logging -from PyViCare.PyViCareDevice import Device +from PyViCare.PyViCareDevice import Device as PyViCareDevice from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig +from PyViCare.PyViCareHeatingDevice import ( + HeatingDeviceWithComponent as PyViCareHeatingDeviceWithComponent, +) from PyViCare.PyViCareUtils import ( PyViCareInvalidDataError, PyViCareNotSupportedFeatureError, @@ -59,7 +62,7 @@ VICARE_UNIT_TO_DEVICE_CLASS = { class ViCareSensorEntityDescription(SensorEntityDescription, ViCareRequiredKeysMixin): """Describes ViCare sensor entity.""" - unit_getter: Callable[[Device], str | None] | None = None + unit_getter: Callable[[PyViCareDevice], str | None] | None = None GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = ( @@ -628,45 +631,86 @@ async def _entities_from_descriptions( entities.append(entity) +def _build_entities( + device: PyViCareDevice, + device_config: PyViCareDeviceConfig, +) -> list[ViCareSensor]: + """Create ViCare sensor entities for a device.""" + + entities: list[ViCareSensor] = _build_entities_for_device(device, device_config) + entities.extend( + _build_entities_for_component( + get_circuits(device), device_config, CIRCUIT_SENSORS + ) + ) + entities.extend( + _build_entities_for_component( + get_burners(device), device_config, BURNER_SENSORS + ) + ) + entities.extend( + _build_entities_for_component( + get_compressors(device), device_config, COMPRESSOR_SENSORS + ) + ) + return entities + + +def _build_entities_for_device( + device: PyViCareDevice, + device_config: PyViCareDeviceConfig, +) -> list[ViCareSensor]: + """Create device specific ViCare sensor entities.""" + + return [ + ViCareSensor( + device, + device_config, + description, + ) + for description in GLOBAL_SENSORS + if is_supported(description.key, description, device) + ] + + +def _build_entities_for_component( + components: list[PyViCareHeatingDeviceWithComponent], + device_config: PyViCareDeviceConfig, + entity_descriptions: tuple[ViCareSensorEntityDescription, ...], +) -> list[ViCareSensor]: + """Create component specific ViCare sensor entities.""" + + return [ + ViCareSensor( + component, + device_config, + description, + ) + for component in components + for description in entity_descriptions + if is_supported(description.key, description, component) + ] + + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Create the ViCare sensor devices.""" - api: Device = hass.data[DOMAIN][config_entry.entry_id][VICARE_API] + api: PyViCareDevice = hass.data[DOMAIN][config_entry.entry_id][VICARE_API] device_config: PyViCareDeviceConfig = hass.data[DOMAIN][config_entry.entry_id][ VICARE_DEVICE_CONFIG ] - entities = [] - for description in GLOBAL_SENSORS: - entity = await hass.async_add_executor_job( - _build_entity, + async_add_entities( + await hass.async_add_executor_job( + _build_entities, api, device_config, - description, ) - if entity: - entities.append(entity) - - circuits = await hass.async_add_executor_job(get_circuits, api) - await _entities_from_descriptions( - hass, entities, CIRCUIT_SENSORS, circuits, config_entry ) - burners = await hass.async_add_executor_job(get_burners, api) - await _entities_from_descriptions( - hass, entities, BURNER_SENSORS, burners, config_entry - ) - - compressors = await hass.async_add_executor_job(get_compressors, api) - await _entities_from_descriptions( - hass, entities, COMPRESSOR_SENSORS, compressors, config_entry - ) - - async_add_entities(entities) - class ViCareSensor(ViCareEntity, SensorEntity): """Representation of a ViCare sensor.""" diff --git a/homeassistant/components/vicare/water_heater.py b/homeassistant/components/vicare/water_heater.py index 9b154da2bc2..036ced5ee55 100644 --- a/homeassistant/components/vicare/water_heater.py +++ b/homeassistant/components/vicare/water_heater.py @@ -1,4 +1,6 @@ """Viessmann ViCare water_heater device.""" +from __future__ import annotations + from contextlib import suppress import logging from typing import Any @@ -58,27 +60,38 @@ HA_TO_VICARE_HVAC_DHW = { } +def _build_entities( + api: PyViCareDevice, + device_config: PyViCareDeviceConfig, +) -> list[ViCareWater]: + """Create ViCare water entities for a device.""" + return [ + ViCareWater( + api, + circuit, + device_config, + "water", + ) + for circuit in get_circuits(api) + ] + + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the ViCare climate platform.""" - entities = [] api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API] device_config = hass.data[DOMAIN][config_entry.entry_id][VICARE_DEVICE_CONFIG] - circuits = await hass.async_add_executor_job(get_circuits, api) - for circuit in circuits: - entity = ViCareWater( + async_add_entities( + await hass.async_add_executor_job( + _build_entities, api, - circuit, device_config, - "water", ) - entities.append(entity) - - async_add_entities(entities) + ) class ViCareWater(ViCareEntity, WaterHeaterEntity):