Improve code quality for ViCare integration (#124613)
* move type to module * set translation key outside of init * align import alias * align constructor parameter order/naming * move static attr init outside init function * add missing types * fix test * revert move of _attributes
This commit is contained in:
parent
bb6f9ec844
commit
0591b5e47b
9 changed files with 85 additions and 87 deletions
|
@ -10,7 +10,7 @@ import logging
|
||||||
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
||||||
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||||
from PyViCare.PyViCareHeatingDevice import (
|
from PyViCare.PyViCareHeatingDevice import (
|
||||||
HeatingDeviceWithComponent as PyViCareHeatingDeviceWithComponent,
|
HeatingDeviceWithComponent as PyViCareHeatingDeviceComponent,
|
||||||
)
|
)
|
||||||
from PyViCare.PyViCareUtils import (
|
from PyViCare.PyViCareUtils import (
|
||||||
PyViCareInvalidDataError,
|
PyViCareInvalidDataError,
|
||||||
|
@ -139,8 +139,8 @@ def _build_entities_for_device(
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ViCareBinarySensor(
|
ViCareBinarySensor(
|
||||||
device,
|
|
||||||
device_config,
|
device_config,
|
||||||
|
device,
|
||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
for description in GLOBAL_SENSORS
|
for description in GLOBAL_SENSORS
|
||||||
|
@ -149,7 +149,7 @@ def _build_entities_for_device(
|
||||||
|
|
||||||
|
|
||||||
def _build_entities_for_component(
|
def _build_entities_for_component(
|
||||||
components: list[PyViCareHeatingDeviceWithComponent],
|
components: list[PyViCareHeatingDeviceComponent],
|
||||||
device_config: PyViCareDeviceConfig,
|
device_config: PyViCareDeviceConfig,
|
||||||
entity_descriptions: tuple[ViCareBinarySensorEntityDescription, ...],
|
entity_descriptions: tuple[ViCareBinarySensorEntityDescription, ...],
|
||||||
) -> list[ViCareBinarySensor]:
|
) -> list[ViCareBinarySensor]:
|
||||||
|
@ -157,8 +157,8 @@ def _build_entities_for_component(
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ViCareBinarySensor(
|
ViCareBinarySensor(
|
||||||
component,
|
|
||||||
device_config,
|
device_config,
|
||||||
|
component,
|
||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
for component in components
|
for component in components
|
||||||
|
@ -190,8 +190,8 @@ class ViCareBinarySensor(ViCareEntity, BinarySensorEntity):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api: PyViCareDevice,
|
|
||||||
device_config: PyViCareDeviceConfig,
|
device_config: PyViCareDeviceConfig,
|
||||||
|
api: PyViCareDevice | PyViCareHeatingDeviceComponent,
|
||||||
description: ViCareBinarySensorEntityDescription,
|
description: ViCareBinarySensorEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the sensor."""
|
"""Initialize the sensor."""
|
||||||
|
|
|
@ -54,8 +54,8 @@ def _build_entities(
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ViCareButton(
|
ViCareButton(
|
||||||
device.api,
|
|
||||||
device.config,
|
device.config,
|
||||||
|
device.api,
|
||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
for device in device_list
|
for device in device_list
|
||||||
|
@ -87,12 +87,12 @@ class ViCareButton(ViCareEntity, ButtonEntity):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api: PyViCareDevice,
|
|
||||||
device_config: PyViCareDeviceConfig,
|
device_config: PyViCareDeviceConfig,
|
||||||
|
device: PyViCareDevice,
|
||||||
description: ViCareButtonEntityDescription,
|
description: ViCareButtonEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the button."""
|
"""Initialize the button."""
|
||||||
super().__init__(device_config, api, description.key)
|
super().__init__(device_config, device, description.key)
|
||||||
self.entity_description = description
|
self.entity_description = description
|
||||||
|
|
||||||
def press(self) -> None:
|
def press(self) -> None:
|
||||||
|
|
|
@ -87,10 +87,9 @@ def _build_entities(
|
||||||
"""Create ViCare climate entities for a device."""
|
"""Create ViCare climate entities for a device."""
|
||||||
return [
|
return [
|
||||||
ViCareClimate(
|
ViCareClimate(
|
||||||
|
device.config,
|
||||||
device.api,
|
device.api,
|
||||||
circuit,
|
circuit,
|
||||||
device.config,
|
|
||||||
"heating",
|
|
||||||
)
|
)
|
||||||
for device in device_list
|
for device in device_list
|
||||||
for circuit in get_circuits(device.api)
|
for circuit in get_circuits(device.api)
|
||||||
|
@ -136,24 +135,22 @@ class ViCareClimate(ViCareEntity, ClimateEntity):
|
||||||
_attr_min_temp = VICARE_TEMP_HEATING_MIN
|
_attr_min_temp = VICARE_TEMP_HEATING_MIN
|
||||||
_attr_max_temp = VICARE_TEMP_HEATING_MAX
|
_attr_max_temp = VICARE_TEMP_HEATING_MAX
|
||||||
_attr_target_temperature_step = PRECISION_WHOLE
|
_attr_target_temperature_step = PRECISION_WHOLE
|
||||||
|
_attr_translation_key = "heating"
|
||||||
_current_action: bool | None = None
|
_current_action: bool | None = None
|
||||||
_current_mode: str | None = None
|
_current_mode: str | None = None
|
||||||
|
_current_program: str | None = None
|
||||||
_enable_turn_on_off_backwards_compatibility = False
|
_enable_turn_on_off_backwards_compatibility = False
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api: PyViCareDevice,
|
|
||||||
circuit: PyViCareHeatingCircuit,
|
|
||||||
device_config: PyViCareDeviceConfig,
|
device_config: PyViCareDeviceConfig,
|
||||||
translation_key: str,
|
device: PyViCareDevice,
|
||||||
|
circuit: PyViCareHeatingCircuit,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the climate device."""
|
"""Initialize the climate device."""
|
||||||
super().__init__(device_config, api, circuit.id)
|
super().__init__(device_config, device, circuit.id)
|
||||||
self._circuit = circuit
|
self._circuit = circuit
|
||||||
self._attributes: dict[str, Any] = {}
|
self._attributes: dict[str, Any] = {}
|
||||||
self._current_program = None
|
|
||||||
self._attr_translation_key = translation_key
|
|
||||||
|
|
||||||
self._attributes["vicare_programs"] = self._circuit.getPrograms()
|
self._attributes["vicare_programs"] = self._circuit.getPrograms()
|
||||||
self._attr_preset_modes = [
|
self._attr_preset_modes = [
|
||||||
preset
|
preset
|
||||||
|
@ -340,7 +337,7 @@ class ViCareClimate(ViCareEntity, ClimateEntity):
|
||||||
) from err
|
) from err
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self):
|
def extra_state_attributes(self) -> dict[str, Any]:
|
||||||
"""Show Device Attributes."""
|
"""Show Device Attributes."""
|
||||||
return self._attributes
|
return self._attributes
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
|
import enum
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
||||||
|
@ -28,10 +29,58 @@ from homeassistant.util.percentage import (
|
||||||
|
|
||||||
from .const import DEVICE_LIST, DOMAIN
|
from .const import DEVICE_LIST, DOMAIN
|
||||||
from .entity import ViCareEntity
|
from .entity import ViCareEntity
|
||||||
from .types import VentilationMode, VentilationProgram
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class VentilationProgram(enum.StrEnum):
|
||||||
|
"""ViCare preset ventilation programs.
|
||||||
|
|
||||||
|
As listed in https://github.com/somm15/PyViCare/blob/6c5b023ca6c8bb2d38141dd1746dc1705ec84ce8/PyViCare/PyViCareVentilationDevice.py#L37
|
||||||
|
"""
|
||||||
|
|
||||||
|
LEVEL_ONE = "levelOne"
|
||||||
|
LEVEL_TWO = "levelTwo"
|
||||||
|
LEVEL_THREE = "levelThree"
|
||||||
|
LEVEL_FOUR = "levelFour"
|
||||||
|
|
||||||
|
|
||||||
|
class VentilationMode(enum.StrEnum):
|
||||||
|
"""ViCare ventilation modes."""
|
||||||
|
|
||||||
|
PERMANENT = "permanent" # on, speed controlled by program (levelOne-levelFour)
|
||||||
|
VENTILATION = "ventilation" # activated by schedule
|
||||||
|
SENSOR_DRIVEN = "sensor_driven" # activated by schedule, override by sensor
|
||||||
|
SENSOR_OVERRIDE = "sensor_override" # activated by sensor
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def to_vicare_mode(mode: str | None) -> str | None:
|
||||||
|
"""Return the mapped ViCare ventilation mode for the Home Assistant mode."""
|
||||||
|
if mode:
|
||||||
|
try:
|
||||||
|
ventilation_mode = VentilationMode(mode)
|
||||||
|
except ValueError:
|
||||||
|
# ignore unsupported / unmapped modes
|
||||||
|
return None
|
||||||
|
return HA_TO_VICARE_MODE_VENTILATION.get(ventilation_mode) if mode else None
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_vicare_mode(vicare_mode: str | None) -> str | None:
|
||||||
|
"""Return the mapped Home Assistant mode for the ViCare ventilation mode."""
|
||||||
|
for mode in VentilationMode:
|
||||||
|
if HA_TO_VICARE_MODE_VENTILATION.get(VentilationMode(mode)) == vicare_mode:
|
||||||
|
return mode
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
HA_TO_VICARE_MODE_VENTILATION = {
|
||||||
|
VentilationMode.PERMANENT: "permanent",
|
||||||
|
VentilationMode.VENTILATION: "ventilation",
|
||||||
|
VentilationMode.SENSOR_DRIVEN: "sensorDriven",
|
||||||
|
VentilationMode.SENSOR_OVERRIDE: "sensorOverride",
|
||||||
|
}
|
||||||
|
|
||||||
ORDERED_NAMED_FAN_SPEEDS = [
|
ORDERED_NAMED_FAN_SPEEDS = [
|
||||||
VentilationProgram.LEVEL_ONE,
|
VentilationProgram.LEVEL_ONE,
|
||||||
VentilationProgram.LEVEL_TWO,
|
VentilationProgram.LEVEL_TWO,
|
||||||
|
|
|
@ -235,8 +235,8 @@ def _build_entities(
|
||||||
|
|
||||||
entities: list[ViCareNumber] = [
|
entities: list[ViCareNumber] = [
|
||||||
ViCareNumber(
|
ViCareNumber(
|
||||||
device.api,
|
|
||||||
device.config,
|
device.config,
|
||||||
|
device.api,
|
||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
for device in device_list
|
for device in device_list
|
||||||
|
@ -247,8 +247,8 @@ def _build_entities(
|
||||||
entities.extend(
|
entities.extend(
|
||||||
[
|
[
|
||||||
ViCareNumber(
|
ViCareNumber(
|
||||||
circuit,
|
|
||||||
device.config,
|
device.config,
|
||||||
|
circuit,
|
||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
for device in device_list
|
for device in device_list
|
||||||
|
@ -283,8 +283,8 @@ class ViCareNumber(ViCareEntity, NumberEntity):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api: PyViCareHeatingDeviceComponent,
|
|
||||||
device_config: PyViCareDeviceConfig,
|
device_config: PyViCareDeviceConfig,
|
||||||
|
api: PyViCareDevice | PyViCareHeatingDeviceComponent,
|
||||||
description: ViCareNumberEntityDescription,
|
description: ViCareNumberEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the number."""
|
"""Initialize the number."""
|
||||||
|
|
|
@ -10,7 +10,7 @@ import logging
|
||||||
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
||||||
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||||
from PyViCare.PyViCareHeatingDevice import (
|
from PyViCare.PyViCareHeatingDevice import (
|
||||||
HeatingDeviceWithComponent as PyViCareHeatingDeviceWithComponent,
|
HeatingDeviceWithComponent as PyViCareHeatingDeviceComponent,
|
||||||
)
|
)
|
||||||
from PyViCare.PyViCareUtils import (
|
from PyViCare.PyViCareUtils import (
|
||||||
PyViCareInvalidDataError,
|
PyViCareInvalidDataError,
|
||||||
|
@ -892,8 +892,8 @@ def _build_entities_for_device(
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ViCareSensor(
|
ViCareSensor(
|
||||||
device,
|
|
||||||
device_config,
|
device_config,
|
||||||
|
device,
|
||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
for description in GLOBAL_SENSORS
|
for description in GLOBAL_SENSORS
|
||||||
|
@ -902,7 +902,7 @@ def _build_entities_for_device(
|
||||||
|
|
||||||
|
|
||||||
def _build_entities_for_component(
|
def _build_entities_for_component(
|
||||||
components: list[PyViCareHeatingDeviceWithComponent],
|
components: list[PyViCareHeatingDeviceComponent],
|
||||||
device_config: PyViCareDeviceConfig,
|
device_config: PyViCareDeviceConfig,
|
||||||
entity_descriptions: tuple[ViCareSensorEntityDescription, ...],
|
entity_descriptions: tuple[ViCareSensorEntityDescription, ...],
|
||||||
) -> list[ViCareSensor]:
|
) -> list[ViCareSensor]:
|
||||||
|
@ -910,8 +910,8 @@ def _build_entities_for_component(
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ViCareSensor(
|
ViCareSensor(
|
||||||
component,
|
|
||||||
device_config,
|
device_config,
|
||||||
|
component,
|
||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
for component in components
|
for component in components
|
||||||
|
@ -943,8 +943,8 @@ class ViCareSensor(ViCareEntity, SensorEntity):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api,
|
|
||||||
device_config: PyViCareDeviceConfig,
|
device_config: PyViCareDeviceConfig,
|
||||||
|
api: PyViCareDevice | PyViCareHeatingDeviceComponent,
|
||||||
description: ViCareSensorEntityDescription,
|
description: ViCareSensorEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the sensor."""
|
"""Initialize the sensor."""
|
||||||
|
|
|
@ -64,55 +64,6 @@ VICARE_TO_HA_PRESET_HEATING = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class VentilationMode(enum.StrEnum):
|
|
||||||
"""ViCare ventilation modes."""
|
|
||||||
|
|
||||||
PERMANENT = "permanent" # on, speed controlled by program (levelOne-levelFour)
|
|
||||||
VENTILATION = "ventilation" # activated by schedule
|
|
||||||
SENSOR_DRIVEN = "sensor_driven" # activated by schedule, override by sensor
|
|
||||||
SENSOR_OVERRIDE = "sensor_override" # activated by sensor
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def to_vicare_mode(mode: str | None) -> str | None:
|
|
||||||
"""Return the mapped ViCare ventilation mode for the Home Assistant mode."""
|
|
||||||
if mode:
|
|
||||||
try:
|
|
||||||
ventilation_mode = VentilationMode(mode)
|
|
||||||
except ValueError:
|
|
||||||
# ignore unsupported / unmapped modes
|
|
||||||
return None
|
|
||||||
return HA_TO_VICARE_MODE_VENTILATION.get(ventilation_mode) if mode else None
|
|
||||||
return None
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def from_vicare_mode(vicare_mode: str | None) -> str | None:
|
|
||||||
"""Return the mapped Home Assistant mode for the ViCare ventilation mode."""
|
|
||||||
for mode in VentilationMode:
|
|
||||||
if HA_TO_VICARE_MODE_VENTILATION.get(VentilationMode(mode)) == vicare_mode:
|
|
||||||
return mode
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
HA_TO_VICARE_MODE_VENTILATION = {
|
|
||||||
VentilationMode.PERMANENT: "permanent",
|
|
||||||
VentilationMode.VENTILATION: "ventilation",
|
|
||||||
VentilationMode.SENSOR_DRIVEN: "sensorDriven",
|
|
||||||
VentilationMode.SENSOR_OVERRIDE: "sensorOverride",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class VentilationProgram(enum.StrEnum):
|
|
||||||
"""ViCare preset ventilation programs.
|
|
||||||
|
|
||||||
As listed in https://github.com/somm15/PyViCare/blob/6c5b023ca6c8bb2d38141dd1746dc1705ec84ce8/PyViCare/PyViCareVentilationDevice.py#L37
|
|
||||||
"""
|
|
||||||
|
|
||||||
LEVEL_ONE = "levelOne"
|
|
||||||
LEVEL_TWO = "levelTwo"
|
|
||||||
LEVEL_THREE = "levelThree"
|
|
||||||
LEVEL_FOUR = "levelFour"
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ViCareDevice:
|
class ViCareDevice:
|
||||||
"""Dataclass holding the device api and config."""
|
"""Dataclass holding the device api and config."""
|
||||||
|
|
|
@ -69,10 +69,9 @@ def _build_entities(
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ViCareWater(
|
ViCareWater(
|
||||||
|
device.config,
|
||||||
device.api,
|
device.api,
|
||||||
circuit,
|
circuit,
|
||||||
device.config,
|
|
||||||
"domestic_hot_water",
|
|
||||||
)
|
)
|
||||||
for device in device_list
|
for device in device_list
|
||||||
for circuit in get_circuits(device.api)
|
for circuit in get_circuits(device.api)
|
||||||
|
@ -104,20 +103,19 @@ class ViCareWater(ViCareEntity, WaterHeaterEntity):
|
||||||
_attr_min_temp = VICARE_TEMP_WATER_MIN
|
_attr_min_temp = VICARE_TEMP_WATER_MIN
|
||||||
_attr_max_temp = VICARE_TEMP_WATER_MAX
|
_attr_max_temp = VICARE_TEMP_WATER_MAX
|
||||||
_attr_operation_list = list(HA_TO_VICARE_HVAC_DHW)
|
_attr_operation_list = list(HA_TO_VICARE_HVAC_DHW)
|
||||||
|
_attr_translation_key = "domestic_hot_water"
|
||||||
|
_current_mode: str | None = None
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api: PyViCareDevice,
|
|
||||||
circuit: PyViCareHeatingCircuit,
|
|
||||||
device_config: PyViCareDeviceConfig,
|
device_config: PyViCareDeviceConfig,
|
||||||
translation_key: str,
|
device: PyViCareDevice,
|
||||||
|
circuit: PyViCareHeatingCircuit,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the DHW water_heater device."""
|
"""Initialize the DHW water_heater device."""
|
||||||
super().__init__(device_config, api, circuit.id)
|
super().__init__(device_config, device, circuit.id)
|
||||||
self._circuit = circuit
|
self._circuit = circuit
|
||||||
self._attributes: dict[str, Any] = {}
|
self._attributes: dict[str, Any] = {}
|
||||||
self._current_mode = None
|
|
||||||
self._attr_translation_key = translation_key
|
|
||||||
|
|
||||||
def update(self) -> None:
|
def update(self) -> None:
|
||||||
"""Let HA know there has been an update from the ViCare API."""
|
"""Let HA know there has been an update from the ViCare API."""
|
||||||
|
@ -151,6 +149,8 @@ class ViCareWater(ViCareEntity, WaterHeaterEntity):
|
||||||
self._attr_target_temperature = temp
|
self._attr_target_temperature = temp
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_operation(self):
|
def current_operation(self) -> str | None:
|
||||||
"""Return current operation ie. heat, cool, idle."""
|
"""Return current operation ie. heat, cool, idle."""
|
||||||
return VICARE_TO_HA_HVAC_DHW.get(self._current_mode)
|
if self._current_mode is None:
|
||||||
|
return None
|
||||||
|
return VICARE_TO_HA_HVAC_DHW.get(self._current_mode, None)
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.climate import PRESET_COMFORT, PRESET_SLEEP
|
from homeassistant.components.climate import PRESET_COMFORT, PRESET_SLEEP
|
||||||
from homeassistant.components.vicare.types import HeatingProgram, VentilationMode
|
from homeassistant.components.vicare.fan import VentilationMode
|
||||||
|
from homeassistant.components.vicare.types import HeatingProgram
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
|
Loading…
Add table
Reference in a new issue