Use EntityDescription - vicare (#55932)

* Use EntityDescription - vicare binary_sensor

* Use EntityDescription - vicare sensor

* Fix typing

* Remove default values

* Fix pylint
This commit is contained in:
Marc Mueller 2021-09-14 22:06:06 +02:00 committed by GitHub
parent 0364922d80
commit 2b51896d7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 319 additions and 272 deletions

View File

@ -1,6 +1,10 @@
"""The ViCare integration.""" """The ViCare integration."""
from __future__ import annotations
from dataclasses import dataclass
import enum import enum
import logging import logging
from typing import Callable, Generic, TypeVar
from PyViCare.PyViCareDevice import Device from PyViCare.PyViCareDevice import Device
from PyViCare.PyViCareFuelCell import FuelCell from PyViCare.PyViCareFuelCell import FuelCell
@ -33,6 +37,16 @@ CONF_HEATING_TYPE = "heating_type"
DEFAULT_HEATING_TYPE = "generic" DEFAULT_HEATING_TYPE = "generic"
ApiT = TypeVar("ApiT", bound=Device)
@dataclass()
class ViCareRequiredKeysMixin(Generic[ApiT]):
"""Mixin for required keys."""
value_getter: Callable[[ApiT], bool]
class HeatingType(enum.Enum): class HeatingType(enum.Enum):
"""Possible options for heating type.""" """Possible options for heating type."""

View File

@ -1,28 +1,35 @@
"""Viessmann ViCare sensor device.""" """Viessmann ViCare sensor device."""
from __future__ import annotations
from contextlib import suppress from contextlib import suppress
from dataclasses import dataclass
import logging import logging
from typing import Union
from PyViCare.PyViCare import PyViCareNotSupportedFeatureError, PyViCareRateLimitError from PyViCare.PyViCare import PyViCareNotSupportedFeatureError, PyViCareRateLimitError
from PyViCare.PyViCareDevice import Device
from PyViCare.PyViCareGazBoiler import GazBoiler
from PyViCare.PyViCareHeatPump import HeatPump
import requests import requests
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
DEVICE_CLASS_POWER, DEVICE_CLASS_POWER,
BinarySensorEntity, BinarySensorEntity,
BinarySensorEntityDescription,
) )
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME
from . import ( from . import (
DOMAIN as VICARE_DOMAIN, DOMAIN as VICARE_DOMAIN,
VICARE_API, VICARE_API,
VICARE_HEATING_TYPE, VICARE_HEATING_TYPE,
VICARE_NAME, VICARE_NAME,
ApiT,
HeatingType, HeatingType,
ViCareRequiredKeysMixin,
) )
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_GETTER = "getter"
SENSOR_CIRCULATION_PUMP_ACTIVE = "circulationpump_active" SENSOR_CIRCULATION_PUMP_ACTIVE = "circulationpump_active"
# gas sensors # gas sensors
@ -31,33 +38,46 @@ SENSOR_BURNER_ACTIVE = "burner_active"
# heatpump sensors # heatpump sensors
SENSOR_COMPRESSOR_ACTIVE = "compressor_active" SENSOR_COMPRESSOR_ACTIVE = "compressor_active"
SENSOR_TYPES = {
SENSOR_CIRCULATION_PUMP_ACTIVE: { @dataclass
CONF_NAME: "Circulation pump active", class ViCareBinarySensorEntityDescription(
CONF_DEVICE_CLASS: DEVICE_CLASS_POWER, BinarySensorEntityDescription, ViCareRequiredKeysMixin[ApiT]
CONF_GETTER: lambda api: api.getCirculationPumpActive(), ):
}, """Describes ViCare binary sensor entity."""
# gas sensors
SENSOR_BURNER_ACTIVE: {
CONF_NAME: "Burner active", SENSOR_TYPES_GENERIC: tuple[ViCareBinarySensorEntityDescription[Device]] = (
CONF_DEVICE_CLASS: DEVICE_CLASS_POWER, ViCareBinarySensorEntityDescription[Device](
CONF_GETTER: lambda api: api.getBurnerActive(), key=SENSOR_CIRCULATION_PUMP_ACTIVE,
}, name="Circulation pump active",
# heatpump sensors device_class=DEVICE_CLASS_POWER,
SENSOR_COMPRESSOR_ACTIVE: { value_getter=lambda api: api.getCirculationPumpActive(),
CONF_NAME: "Compressor active", ),
CONF_DEVICE_CLASS: DEVICE_CLASS_POWER, )
CONF_GETTER: lambda api: api.getCompressorActive(),
}, SENSOR_TYPES_GAS: tuple[ViCareBinarySensorEntityDescription[GazBoiler]] = (
} ViCareBinarySensorEntityDescription[GazBoiler](
key=SENSOR_BURNER_ACTIVE,
name="Burner active",
device_class=DEVICE_CLASS_POWER,
value_getter=lambda api: api.getBurnerActive(),
),
)
SENSOR_TYPES_HEATPUMP: tuple[ViCareBinarySensorEntityDescription[HeatPump]] = (
ViCareBinarySensorEntityDescription[HeatPump](
key=SENSOR_COMPRESSOR_ACTIVE,
name="Compressor active",
device_class=DEVICE_CLASS_POWER,
value_getter=lambda api: api.getCompressorActive(),
),
)
SENSORS_GENERIC = [SENSOR_CIRCULATION_PUMP_ACTIVE] SENSORS_GENERIC = [SENSOR_CIRCULATION_PUMP_ACTIVE]
SENSORS_BY_HEATINGTYPE = { SENSORS_BY_HEATINGTYPE = {
HeatingType.gas: [SENSOR_BURNER_ACTIVE], HeatingType.gas: [SENSOR_BURNER_ACTIVE],
HeatingType.heatpump: [ HeatingType.heatpump: [SENSOR_COMPRESSOR_ACTIVE],
SENSOR_COMPRESSOR_ACTIVE,
],
HeatingType.fuelcell: [SENSOR_BURNER_ACTIVE], HeatingType.fuelcell: [SENSOR_BURNER_ACTIVE],
} }
@ -78,22 +98,34 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
add_entities( add_entities(
[ [
ViCareBinarySensor( ViCareBinarySensor(
hass.data[VICARE_DOMAIN][VICARE_NAME], vicare_api, sensor hass.data[VICARE_DOMAIN][VICARE_NAME], vicare_api, description
) )
for sensor in sensors for description in (
*SENSOR_TYPES_GENERIC,
*SENSOR_TYPES_GAS,
*SENSOR_TYPES_HEATPUMP,
)
if description.key in sensors
] ]
) )
DescriptionT = Union[
ViCareBinarySensorEntityDescription[Device],
ViCareBinarySensorEntityDescription[GazBoiler],
ViCareBinarySensorEntityDescription[HeatPump],
]
class ViCareBinarySensor(BinarySensorEntity): class ViCareBinarySensor(BinarySensorEntity):
"""Representation of a ViCare sensor.""" """Representation of a ViCare sensor."""
def __init__(self, name, api, sensor_type): entity_description: DescriptionT
def __init__(self, name, api, description: DescriptionT):
"""Initialize the sensor.""" """Initialize the sensor."""
self._sensor = SENSOR_TYPES[sensor_type] self._attr_name = f"{name} {description.name}"
self._name = f"{name} {self._sensor[CONF_NAME]}"
self._api = api self._api = api
self._sensor_type = sensor_type
self._state = None self._state = None
@property @property
@ -104,28 +136,18 @@ class ViCareBinarySensor(BinarySensorEntity):
@property @property
def unique_id(self): def unique_id(self):
"""Return a unique ID.""" """Return a unique ID."""
return f"{self._api.service.id}-{self._sensor_type}" return f"{self._api.service.id}-{self.entity_description.key}"
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property @property
def is_on(self): def is_on(self):
"""Return the state of the sensor.""" """Return the state of the sensor."""
return self._state return self._state
@property
def device_class(self):
"""Return the class of this device, from component DEVICE_CLASSES."""
return self._sensor[CONF_DEVICE_CLASS]
def update(self): def update(self):
"""Update state of sensor.""" """Update state of sensor."""
try: try:
with suppress(PyViCareNotSupportedFeatureError): with suppress(PyViCareNotSupportedFeatureError):
self._state = self._sensor[CONF_GETTER](self._api) self._state = self.entity_description.value_getter(self._api)
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
_LOGGER.error("Unable to retrieve data from ViCare server") _LOGGER.error("Unable to retrieve data from ViCare server")
except ValueError: except ValueError:

View File

@ -1,16 +1,20 @@
"""Viessmann ViCare sensor device.""" """Viessmann ViCare sensor device."""
from __future__ import annotations
from contextlib import suppress from contextlib import suppress
from dataclasses import dataclass
import logging import logging
from typing import Union
from PyViCare.PyViCare import PyViCareNotSupportedFeatureError, PyViCareRateLimitError from PyViCare.PyViCare import PyViCareNotSupportedFeatureError, PyViCareRateLimitError
from PyViCare.PyViCareDevice import Device
from PyViCare.PyViCareFuelCell import FuelCell
from PyViCare.PyViCareGazBoiler import GazBoiler
from PyViCare.PyViCareHeatPump import HeatPump
import requests import requests
from homeassistant.components.sensor import SensorEntity from homeassistant.components.sensor import SensorEntity, SensorEntityDescription
from homeassistant.const import ( from homeassistant.const import (
CONF_DEVICE_CLASS,
CONF_ICON,
CONF_NAME,
CONF_UNIT_OF_MEASUREMENT,
DEVICE_CLASS_ENERGY, DEVICE_CLASS_ENERGY,
DEVICE_CLASS_POWER, DEVICE_CLASS_POWER,
DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_TEMPERATURE,
@ -26,13 +30,13 @@ from . import (
VICARE_API, VICARE_API,
VICARE_HEATING_TYPE, VICARE_HEATING_TYPE,
VICARE_NAME, VICARE_NAME,
ApiT,
HeatingType, HeatingType,
ViCareRequiredKeysMixin,
) )
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_GETTER = "getter"
SENSOR_TYPE_TEMPERATURE = "temperature" SENSOR_TYPE_TEMPERATURE = "temperature"
SENSOR_OUTSIDE_TEMPERATURE = "outside_temperature" SENSOR_OUTSIDE_TEMPERATURE = "outside_temperature"
@ -70,200 +74,212 @@ SENSOR_POWER_PRODUCTION_THIS_WEEK = "power_production_this_week"
SENSOR_POWER_PRODUCTION_THIS_MONTH = "power_production_this_month" SENSOR_POWER_PRODUCTION_THIS_MONTH = "power_production_this_month"
SENSOR_POWER_PRODUCTION_THIS_YEAR = "power_production_this_year" SENSOR_POWER_PRODUCTION_THIS_YEAR = "power_production_this_year"
SENSOR_TYPES = {
SENSOR_OUTSIDE_TEMPERATURE: { @dataclass
CONF_NAME: "Outside Temperature", class ViCareSensorEntityDescription(
CONF_ICON: None, SensorEntityDescription, ViCareRequiredKeysMixin[ApiT]
CONF_UNIT_OF_MEASUREMENT: TEMP_CELSIUS, ):
CONF_GETTER: lambda api: api.getOutsideTemperature(), """Describes ViCare sensor entity."""
CONF_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
},
SENSOR_SUPPLY_TEMPERATURE: { SENSOR_TYPES_GENERIC: tuple[ViCareSensorEntityDescription[Device], ...] = (
CONF_NAME: "Supply Temperature", ViCareSensorEntityDescription[Device](
CONF_ICON: None, key=SENSOR_OUTSIDE_TEMPERATURE,
CONF_UNIT_OF_MEASUREMENT: TEMP_CELSIUS, name="Outside Temperature",
CONF_GETTER: lambda api: api.getSupplyTemperature(), native_unit_of_measurement=TEMP_CELSIUS,
CONF_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, value_getter=lambda api: api.getOutsideTemperature(),
}, device_class=DEVICE_CLASS_TEMPERATURE,
# gas sensors ),
SENSOR_BOILER_TEMPERATURE: { ViCareSensorEntityDescription[Device](
CONF_NAME: "Boiler Temperature", key=SENSOR_SUPPLY_TEMPERATURE,
CONF_ICON: None, name="Supply Temperature",
CONF_UNIT_OF_MEASUREMENT: TEMP_CELSIUS, native_unit_of_measurement=TEMP_CELSIUS,
CONF_GETTER: lambda api: api.getBoilerTemperature(), value_getter=lambda api: api.getSupplyTemperature(),
CONF_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, device_class=DEVICE_CLASS_TEMPERATURE,
}, ),
SENSOR_BURNER_MODULATION: { )
CONF_NAME: "Burner modulation",
CONF_ICON: "mdi:percent", SENSOR_TYPES_GAS: tuple[ViCareSensorEntityDescription[GazBoiler], ...] = (
CONF_UNIT_OF_MEASUREMENT: PERCENTAGE, ViCareSensorEntityDescription[GazBoiler](
CONF_GETTER: lambda api: api.getBurnerModulation(), key=SENSOR_BOILER_TEMPERATURE,
CONF_DEVICE_CLASS: None, name="Boiler Temperature",
}, native_unit_of_measurement=TEMP_CELSIUS,
SENSOR_DHW_GAS_CONSUMPTION_TODAY: { value_getter=lambda api: api.getBoilerTemperature(),
CONF_NAME: "Hot water gas consumption today", device_class=DEVICE_CLASS_TEMPERATURE,
CONF_ICON: "mdi:power", ),
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR, ViCareSensorEntityDescription[GazBoiler](
CONF_GETTER: lambda api: api.getGasConsumptionDomesticHotWaterToday(), key=SENSOR_BURNER_MODULATION,
CONF_DEVICE_CLASS: None, name="Burner modulation",
}, icon="mdi:percent",
SENSOR_DHW_GAS_CONSUMPTION_THIS_WEEK: { native_unit_of_measurement=PERCENTAGE,
CONF_NAME: "Hot water gas consumption this week", value_getter=lambda api: api.getBurnerModulation(),
CONF_ICON: "mdi:power", ),
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR, ViCareSensorEntityDescription[GazBoiler](
CONF_GETTER: lambda api: api.getGasConsumptionDomesticHotWaterThisWeek(), key=SENSOR_DHW_GAS_CONSUMPTION_TODAY,
CONF_DEVICE_CLASS: None, name="Hot water gas consumption today",
}, icon="mdi:power",
SENSOR_DHW_GAS_CONSUMPTION_THIS_MONTH: { native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
CONF_NAME: "Hot water gas consumption this month", value_getter=lambda api: api.getGasConsumptionDomesticHotWaterToday(),
CONF_ICON: "mdi:power", ),
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR, ViCareSensorEntityDescription[GazBoiler](
CONF_GETTER: lambda api: api.getGasConsumptionDomesticHotWaterThisMonth(), key=SENSOR_DHW_GAS_CONSUMPTION_THIS_WEEK,
CONF_DEVICE_CLASS: None, name="Hot water gas consumption this week",
}, icon="mdi:power",
SENSOR_DHW_GAS_CONSUMPTION_THIS_YEAR: { native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
CONF_NAME: "Hot water gas consumption this year", value_getter=lambda api: api.getGasConsumptionDomesticHotWaterThisWeek(),
CONF_ICON: "mdi:power", ),
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR, ViCareSensorEntityDescription[GazBoiler](
CONF_GETTER: lambda api: api.getGasConsumptionDomesticHotWaterThisYear(), key=SENSOR_DHW_GAS_CONSUMPTION_THIS_MONTH,
CONF_DEVICE_CLASS: None, name="Hot water gas consumption this month",
}, icon="mdi:power",
SENSOR_GAS_CONSUMPTION_TODAY: { native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
CONF_NAME: "Heating gas consumption today", value_getter=lambda api: api.getGasConsumptionDomesticHotWaterThisMonth(),
CONF_ICON: "mdi:power", ),
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR, ViCareSensorEntityDescription[GazBoiler](
CONF_GETTER: lambda api: api.getGasConsumptionHeatingToday(), key=SENSOR_DHW_GAS_CONSUMPTION_THIS_YEAR,
CONF_DEVICE_CLASS: None, name="Hot water gas consumption this year",
}, icon="mdi:power",
SENSOR_GAS_CONSUMPTION_THIS_WEEK: { native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
CONF_NAME: "Heating gas consumption this week", value_getter=lambda api: api.getGasConsumptionDomesticHotWaterThisYear(),
CONF_ICON: "mdi:power", ),
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR, ViCareSensorEntityDescription[GazBoiler](
CONF_GETTER: lambda api: api.getGasConsumptionHeatingThisWeek(), key=SENSOR_GAS_CONSUMPTION_TODAY,
CONF_DEVICE_CLASS: None, name="Heating gas consumption today",
}, icon="mdi:power",
SENSOR_GAS_CONSUMPTION_THIS_MONTH: { native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
CONF_NAME: "Heating gas consumption this month", value_getter=lambda api: api.getGasConsumptionHeatingToday(),
CONF_ICON: "mdi:power", ),
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR, ViCareSensorEntityDescription[GazBoiler](
CONF_GETTER: lambda api: api.getGasConsumptionHeatingThisMonth(), key=SENSOR_GAS_CONSUMPTION_THIS_WEEK,
CONF_DEVICE_CLASS: None, name="Heating gas consumption this week",
}, icon="mdi:power",
SENSOR_GAS_CONSUMPTION_THIS_YEAR: { native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
CONF_NAME: "Heating gas consumption this year", value_getter=lambda api: api.getGasConsumptionHeatingThisWeek(),
CONF_ICON: "mdi:power", ),
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR, ViCareSensorEntityDescription[GazBoiler](
CONF_GETTER: lambda api: api.getGasConsumptionHeatingThisYear(), key=SENSOR_GAS_CONSUMPTION_THIS_MONTH,
CONF_DEVICE_CLASS: None, name="Heating gas consumption this month",
}, icon="mdi:power",
SENSOR_BURNER_STARTS: { native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
CONF_NAME: "Burner Starts", value_getter=lambda api: api.getGasConsumptionHeatingThisMonth(),
CONF_ICON: "mdi:counter", ),
CONF_UNIT_OF_MEASUREMENT: None, ViCareSensorEntityDescription[GazBoiler](
CONF_GETTER: lambda api: api.getBurnerStarts(), key=SENSOR_GAS_CONSUMPTION_THIS_YEAR,
CONF_DEVICE_CLASS: None, name="Heating gas consumption this year",
}, icon="mdi:power",
SENSOR_BURNER_HOURS: { native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
CONF_NAME: "Burner Hours", value_getter=lambda api: api.getGasConsumptionHeatingThisYear(),
CONF_ICON: "mdi:counter", ),
CONF_UNIT_OF_MEASUREMENT: TIME_HOURS, ViCareSensorEntityDescription[GazBoiler](
CONF_GETTER: lambda api: api.getBurnerHours(), key=SENSOR_BURNER_STARTS,
CONF_DEVICE_CLASS: None, name="Burner Starts",
}, icon="mdi:counter",
# heatpump sensors value_getter=lambda api: api.getBurnerStarts(),
SENSOR_COMPRESSOR_STARTS: { ),
CONF_NAME: "Compressor Starts", ViCareSensorEntityDescription[GazBoiler](
CONF_ICON: "mdi:counter", key=SENSOR_BURNER_HOURS,
CONF_UNIT_OF_MEASUREMENT: None, name="Burner Hours",
CONF_GETTER: lambda api: api.getCompressorStarts(), icon="mdi:counter",
CONF_DEVICE_CLASS: None, native_unit_of_measurement=TIME_HOURS,
}, value_getter=lambda api: api.getBurnerHours(),
SENSOR_COMPRESSOR_HOURS: { ),
CONF_NAME: "Compressor Hours", )
CONF_ICON: "mdi:counter",
CONF_UNIT_OF_MEASUREMENT: TIME_HOURS, SENSOR_TYPES_HEATPUMP: tuple[ViCareSensorEntityDescription[HeatPump], ...] = (
CONF_GETTER: lambda api: api.getCompressorHours(), ViCareSensorEntityDescription[HeatPump](
CONF_DEVICE_CLASS: None, key=SENSOR_COMPRESSOR_STARTS,
}, name="Compressor Starts",
SENSOR_COMPRESSOR_HOURS_LOADCLASS1: { icon="mdi:counter",
CONF_NAME: "Compressor Hours Load Class 1", value_getter=lambda api: api.getCompressorStarts(),
CONF_ICON: "mdi:counter", ),
CONF_UNIT_OF_MEASUREMENT: TIME_HOURS, ViCareSensorEntityDescription[HeatPump](
CONF_GETTER: lambda api: api.getCompressorHoursLoadClass1(), key=SENSOR_COMPRESSOR_HOURS,
CONF_DEVICE_CLASS: None, name="Compressor Hours",
}, icon="mdi:counter",
SENSOR_COMPRESSOR_HOURS_LOADCLASS2: { native_unit_of_measurement=TIME_HOURS,
CONF_NAME: "Compressor Hours Load Class 2", value_getter=lambda api: api.getCompressorHours(),
CONF_ICON: "mdi:counter", ),
CONF_UNIT_OF_MEASUREMENT: TIME_HOURS, ViCareSensorEntityDescription[HeatPump](
CONF_GETTER: lambda api: api.getCompressorHoursLoadClass2(), key=SENSOR_COMPRESSOR_HOURS_LOADCLASS1,
CONF_DEVICE_CLASS: None, name="Compressor Hours Load Class 1",
}, icon="mdi:counter",
SENSOR_COMPRESSOR_HOURS_LOADCLASS3: { native_unit_of_measurement=TIME_HOURS,
CONF_NAME: "Compressor Hours Load Class 3", value_getter=lambda api: api.getCompressorHoursLoadClass1(),
CONF_ICON: "mdi:counter", ),
CONF_UNIT_OF_MEASUREMENT: TIME_HOURS, ViCareSensorEntityDescription[HeatPump](
CONF_GETTER: lambda api: api.getCompressorHoursLoadClass3(), key=SENSOR_COMPRESSOR_HOURS_LOADCLASS2,
CONF_DEVICE_CLASS: None, name="Compressor Hours Load Class 2",
}, icon="mdi:counter",
SENSOR_COMPRESSOR_HOURS_LOADCLASS4: { native_unit_of_measurement=TIME_HOURS,
CONF_NAME: "Compressor Hours Load Class 4", value_getter=lambda api: api.getCompressorHoursLoadClass2(),
CONF_ICON: "mdi:counter", ),
CONF_UNIT_OF_MEASUREMENT: TIME_HOURS, ViCareSensorEntityDescription[HeatPump](
CONF_GETTER: lambda api: api.getCompressorHoursLoadClass4(), key=SENSOR_COMPRESSOR_HOURS_LOADCLASS3,
CONF_DEVICE_CLASS: None, name="Compressor Hours Load Class 3",
}, icon="mdi:counter",
SENSOR_COMPRESSOR_HOURS_LOADCLASS5: { native_unit_of_measurement=TIME_HOURS,
CONF_NAME: "Compressor Hours Load Class 5", value_getter=lambda api: api.getCompressorHoursLoadClass3(),
CONF_ICON: "mdi:counter", ),
CONF_UNIT_OF_MEASUREMENT: TIME_HOURS, ViCareSensorEntityDescription[HeatPump](
CONF_GETTER: lambda api: api.getCompressorHoursLoadClass5(), key=SENSOR_COMPRESSOR_HOURS_LOADCLASS4,
CONF_DEVICE_CLASS: None, name="Compressor Hours Load Class 4",
}, icon="mdi:counter",
SENSOR_RETURN_TEMPERATURE: { native_unit_of_measurement=TIME_HOURS,
CONF_NAME: "Return Temperature", value_getter=lambda api: api.getCompressorHoursLoadClass4(),
CONF_ICON: None, ),
CONF_UNIT_OF_MEASUREMENT: TEMP_CELSIUS, ViCareSensorEntityDescription[HeatPump](
CONF_GETTER: lambda api: api.getReturnTemperature(), key=SENSOR_COMPRESSOR_HOURS_LOADCLASS5,
CONF_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, name="Compressor Hours Load Class 5",
}, icon="mdi:counter",
# fuelcell sensors native_unit_of_measurement=TIME_HOURS,
SENSOR_POWER_PRODUCTION_CURRENT: { value_getter=lambda api: api.getCompressorHoursLoadClass5(),
CONF_NAME: "Power production current", ),
CONF_ICON: None, ViCareSensorEntityDescription[HeatPump](
CONF_UNIT_OF_MEASUREMENT: POWER_WATT, key=SENSOR_RETURN_TEMPERATURE,
CONF_GETTER: lambda api: api.getPowerProductionCurrent(), name="Return Temperature",
CONF_DEVICE_CLASS: DEVICE_CLASS_POWER, native_unit_of_measurement=TEMP_CELSIUS,
}, value_getter=lambda api: api.getReturnTemperature(),
SENSOR_POWER_PRODUCTION_TODAY: { device_class=DEVICE_CLASS_TEMPERATURE,
CONF_NAME: "Power production today", ),
CONF_ICON: None, )
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR,
CONF_GETTER: lambda api: api.getPowerProductionToday(), SENSOR_TYPES_FUELCELL: tuple[ViCareSensorEntityDescription[FuelCell], ...] = (
CONF_DEVICE_CLASS: DEVICE_CLASS_ENERGY, ViCareSensorEntityDescription[FuelCell](
}, key=SENSOR_POWER_PRODUCTION_CURRENT,
SENSOR_POWER_PRODUCTION_THIS_WEEK: { name="Power production current",
CONF_NAME: "Power production this week", native_unit_of_measurement=POWER_WATT,
CONF_ICON: None, value_getter=lambda api: api.getPowerProductionCurrent(),
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR, device_class=DEVICE_CLASS_POWER,
CONF_GETTER: lambda api: api.getPowerProductionThisWeek(), ),
CONF_DEVICE_CLASS: DEVICE_CLASS_ENERGY, ViCareSensorEntityDescription[FuelCell](
}, key=SENSOR_POWER_PRODUCTION_TODAY,
SENSOR_POWER_PRODUCTION_THIS_MONTH: { name="Power production today",
CONF_NAME: "Power production this month", native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
CONF_ICON: None, value_getter=lambda api: api.getPowerProductionToday(),
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR, device_class=DEVICE_CLASS_ENERGY,
CONF_GETTER: lambda api: api.getPowerProductionThisMonth(), ),
CONF_DEVICE_CLASS: DEVICE_CLASS_ENERGY, ViCareSensorEntityDescription[FuelCell](
}, key=SENSOR_POWER_PRODUCTION_THIS_WEEK,
SENSOR_POWER_PRODUCTION_THIS_YEAR: { name="Power production this week",
CONF_NAME: "Power production this year", native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
CONF_ICON: None, value_getter=lambda api: api.getPowerProductionThisWeek(),
CONF_UNIT_OF_MEASUREMENT: ENERGY_KILO_WATT_HOUR, device_class=DEVICE_CLASS_ENERGY,
CONF_GETTER: lambda api: api.getPowerProductionThisYear(), ),
CONF_DEVICE_CLASS: DEVICE_CLASS_ENERGY, ViCareSensorEntityDescription[FuelCell](
}, key=SENSOR_POWER_PRODUCTION_THIS_MONTH,
} name="Power production this month",
native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
value_getter=lambda api: api.getPowerProductionThisMonth(),
device_class=DEVICE_CLASS_ENERGY,
),
ViCareSensorEntityDescription[FuelCell](
key=SENSOR_POWER_PRODUCTION_THIS_YEAR,
name="Power production this year",
native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
value_getter=lambda api: api.getPowerProductionThisYear(),
device_class=DEVICE_CLASS_ENERGY,
),
)
SENSORS_GENERIC = [SENSOR_OUTSIDE_TEMPERATURE, SENSOR_SUPPLY_TEMPERATURE] SENSORS_GENERIC = [SENSOR_OUTSIDE_TEMPERATURE, SENSOR_SUPPLY_TEMPERATURE]
@ -331,21 +347,36 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
add_entities( add_entities(
[ [
ViCareSensor(hass.data[VICARE_DOMAIN][VICARE_NAME], vicare_api, sensor) ViCareSensor(hass.data[VICARE_DOMAIN][VICARE_NAME], vicare_api, description)
for sensor in sensors for description in (
*SENSOR_TYPES_GENERIC,
*SENSOR_TYPES_GAS,
*SENSOR_TYPES_HEATPUMP,
*SENSOR_TYPES_FUELCELL,
)
if description.key in sensors
] ]
) )
DescriptionT = Union[
ViCareSensorEntityDescription[Device],
ViCareSensorEntityDescription[GazBoiler],
ViCareSensorEntityDescription[HeatPump],
ViCareSensorEntityDescription[FuelCell],
]
class ViCareSensor(SensorEntity): class ViCareSensor(SensorEntity):
"""Representation of a ViCare sensor.""" """Representation of a ViCare sensor."""
def __init__(self, name, api, sensor_type): entity_description: DescriptionT
def __init__(self, name, api, description: DescriptionT):
"""Initialize the sensor.""" """Initialize the sensor."""
self._sensor = SENSOR_TYPES[sensor_type] self.entity_description = description
self._name = f"{name} {self._sensor[CONF_NAME]}" self._attr_name = f"{name} {description.name}"
self._api = api self._api = api
self._sensor_type = sensor_type
self._state = None self._state = None
@property @property
@ -356,38 +387,18 @@ class ViCareSensor(SensorEntity):
@property @property
def unique_id(self): def unique_id(self):
"""Return a unique ID.""" """Return a unique ID."""
return f"{self._api.service.id}-{self._sensor_type}" return f"{self._api.service.id}-{self.entity_description.key}"
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return self._sensor[CONF_ICON]
@property @property
def native_value(self): def native_value(self):
"""Return the state of the sensor.""" """Return the state of the sensor."""
return self._state return self._state
@property
def native_unit_of_measurement(self):
"""Return the unit of measurement."""
return self._sensor[CONF_UNIT_OF_MEASUREMENT]
@property
def device_class(self):
"""Return the class of this device, from component DEVICE_CLASSES."""
return self._sensor[CONF_DEVICE_CLASS]
def update(self): def update(self):
"""Update state of sensor.""" """Update state of sensor."""
try: try:
with suppress(PyViCareNotSupportedFeatureError): with suppress(PyViCareNotSupportedFeatureError):
self._state = self._sensor[CONF_GETTER](self._api) self._state = self.entity_description.value_getter(self._api)
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
_LOGGER.error("Unable to retrieve data from ViCare server") _LOGGER.error("Unable to retrieve data from ViCare server")
except ValueError: except ValueError: