Add Sensor descriptions for Bosch SHC (#116775)
* Add Sensor descriptions for Bosch SHC * fix * fix * fix
This commit is contained in:
parent
cb9914becd
commit
da5d975e22
1 changed files with 172 additions and 301 deletions
|
@ -2,12 +2,17 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from boschshcpy import SHCSession
|
||||
from boschshcpy.device import SHCDevice
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
SensorEntity,
|
||||
SensorEntityDescription,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
@ -20,341 +25,207 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
|
||||
from .const import DATA_SESSION, DOMAIN
|
||||
from .entity import SHCEntity
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class SHCSensorEntityDescription(SensorEntityDescription):
|
||||
"""Describes a SHC sensor."""
|
||||
|
||||
value_fn: Callable[[SHCDevice], StateType]
|
||||
attributes_fn: Callable[[SHCDevice], dict[str, Any]] | None = None
|
||||
|
||||
|
||||
TEMPERATURE_SENSOR = "temperature"
|
||||
HUMIDITY_SENSOR = "humidity"
|
||||
VALVE_TAPPET_SENSOR = "valvetappet"
|
||||
PURITY_SENSOR = "purity"
|
||||
AIR_QUALITY_SENSOR = "airquality"
|
||||
TEMPERATURE_RATING_SENSOR = "temperature_rating"
|
||||
HUMIDITY_RATING_SENSOR = "humidity_rating"
|
||||
PURITY_RATING_SENSOR = "purity_rating"
|
||||
POWER_SENSOR = "power"
|
||||
ENERGY_SENSOR = "energy"
|
||||
COMMUNICATION_QUALITY_SENSOR = "communication_quality"
|
||||
|
||||
SENSOR_DESCRIPTIONS: dict[str, SHCSensorEntityDescription] = {
|
||||
TEMPERATURE_SENSOR: SHCSensorEntityDescription(
|
||||
key=TEMPERATURE_SENSOR,
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
value_fn=lambda device: device.temperature,
|
||||
),
|
||||
HUMIDITY_SENSOR: SHCSensorEntityDescription(
|
||||
key=HUMIDITY_SENSOR,
|
||||
device_class=SensorDeviceClass.HUMIDITY,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
value_fn=lambda device: device.humidity,
|
||||
),
|
||||
PURITY_SENSOR: SHCSensorEntityDescription(
|
||||
key=PURITY_SENSOR,
|
||||
translation_key=PURITY_SENSOR,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
||||
value_fn=lambda device: device.purity,
|
||||
),
|
||||
AIR_QUALITY_SENSOR: SHCSensorEntityDescription(
|
||||
key=AIR_QUALITY_SENSOR,
|
||||
translation_key="air_quality",
|
||||
value_fn=lambda device: device.combined_rating.name,
|
||||
attributes_fn=lambda device: {
|
||||
"rating_description": device.description,
|
||||
},
|
||||
),
|
||||
TEMPERATURE_RATING_SENSOR: SHCSensorEntityDescription(
|
||||
key=TEMPERATURE_RATING_SENSOR,
|
||||
translation_key=TEMPERATURE_RATING_SENSOR,
|
||||
value_fn=lambda device: device.temperature_rating.name,
|
||||
),
|
||||
COMMUNICATION_QUALITY_SENSOR: SHCSensorEntityDescription(
|
||||
key=COMMUNICATION_QUALITY_SENSOR,
|
||||
translation_key=COMMUNICATION_QUALITY_SENSOR,
|
||||
value_fn=lambda device: device.communicationquality.name,
|
||||
),
|
||||
HUMIDITY_RATING_SENSOR: SHCSensorEntityDescription(
|
||||
key=HUMIDITY_RATING_SENSOR,
|
||||
translation_key=HUMIDITY_RATING_SENSOR,
|
||||
value_fn=lambda device: device.humidity_rating.name,
|
||||
),
|
||||
PURITY_RATING_SENSOR: SHCSensorEntityDescription(
|
||||
key=PURITY_RATING_SENSOR,
|
||||
translation_key=PURITY_RATING_SENSOR,
|
||||
value_fn=lambda device: device.purity_rating.name,
|
||||
),
|
||||
POWER_SENSOR: SHCSensorEntityDescription(
|
||||
key=POWER_SENSOR,
|
||||
device_class=SensorDeviceClass.POWER,
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
value_fn=lambda device: device.powerconsumption,
|
||||
),
|
||||
ENERGY_SENSOR: SHCSensorEntityDescription(
|
||||
key=ENERGY_SENSOR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
value_fn=lambda device: device.energyconsumption / 1000.0,
|
||||
),
|
||||
VALVE_TAPPET_SENSOR: SHCSensorEntityDescription(
|
||||
key=VALVE_TAPPET_SENSOR,
|
||||
translation_key=VALVE_TAPPET_SENSOR,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
value_fn=lambda device: device.position,
|
||||
attributes_fn=lambda device: {
|
||||
"valve_tappet_state": device.valvestate.name,
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the SHC sensor platform."""
|
||||
entities: list[SensorEntity] = []
|
||||
session: SHCSession = hass.data[DOMAIN][config_entry.entry_id][DATA_SESSION]
|
||||
|
||||
for sensor in session.device_helper.thermostats:
|
||||
entities.append(
|
||||
TemperatureSensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
entities: list[SensorEntity] = [
|
||||
SHCSensor(
|
||||
device,
|
||||
SENSOR_DESCRIPTIONS[sensor_type],
|
||||
session.information.unique_id,
|
||||
config_entry.entry_id,
|
||||
)
|
||||
for device in session.device_helper.thermostats
|
||||
for sensor_type in (TEMPERATURE_SENSOR, VALVE_TAPPET_SENSOR)
|
||||
]
|
||||
|
||||
entities.extend(
|
||||
SHCSensor(
|
||||
device,
|
||||
SENSOR_DESCRIPTIONS[sensor_type],
|
||||
session.information.unique_id,
|
||||
config_entry.entry_id,
|
||||
)
|
||||
entities.append(
|
||||
ValveTappetSensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
for device in session.device_helper.wallthermostats
|
||||
for sensor_type in (TEMPERATURE_SENSOR, HUMIDITY_SENSOR)
|
||||
)
|
||||
|
||||
entities.extend(
|
||||
SHCSensor(
|
||||
device,
|
||||
SENSOR_DESCRIPTIONS[sensor_type],
|
||||
session.information.unique_id,
|
||||
config_entry.entry_id,
|
||||
)
|
||||
for device in session.device_helper.twinguards
|
||||
for sensor_type in (
|
||||
TEMPERATURE_SENSOR,
|
||||
HUMIDITY_SENSOR,
|
||||
PURITY_SENSOR,
|
||||
AIR_QUALITY_SENSOR,
|
||||
TEMPERATURE_RATING_SENSOR,
|
||||
HUMIDITY_RATING_SENSOR,
|
||||
PURITY_RATING_SENSOR,
|
||||
)
|
||||
)
|
||||
|
||||
for sensor in session.device_helper.wallthermostats:
|
||||
entities.append(
|
||||
TemperatureSensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
entities.extend(
|
||||
SHCSensor(
|
||||
device,
|
||||
SENSOR_DESCRIPTIONS[sensor_type],
|
||||
session.information.unique_id,
|
||||
config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
entities.append(
|
||||
HumiditySensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
|
||||
for sensor in session.device_helper.twinguards:
|
||||
entities.append(
|
||||
TemperatureSensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
entities.append(
|
||||
HumiditySensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
entities.append(
|
||||
PuritySensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
entities.append(
|
||||
AirQualitySensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
entities.append(
|
||||
TemperatureRatingSensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
entities.append(
|
||||
HumidityRatingSensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
entities.append(
|
||||
PurityRatingSensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
|
||||
for sensor in (
|
||||
for device in (
|
||||
session.device_helper.smart_plugs + session.device_helper.light_switches_bsm
|
||||
):
|
||||
entities.append(
|
||||
PowerSensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
entities.append(
|
||||
EnergySensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
for sensor_type in (POWER_SENSOR, ENERGY_SENSOR)
|
||||
)
|
||||
|
||||
for sensor in session.device_helper.smart_plugs_compact:
|
||||
entities.append(
|
||||
PowerSensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
entities.append(
|
||||
EnergySensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
)
|
||||
)
|
||||
entities.append(
|
||||
CommunicationQualitySensor(
|
||||
device=sensor,
|
||||
parent_id=session.information.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
entities.extend(
|
||||
SHCSensor(
|
||||
device,
|
||||
SENSOR_DESCRIPTIONS[sensor_type],
|
||||
session.information.unique_id,
|
||||
config_entry.entry_id,
|
||||
)
|
||||
for device in session.device_helper.smart_plugs_compact
|
||||
for sensor_type in (POWER_SENSOR, ENERGY_SENSOR, COMMUNICATION_QUALITY_SENSOR)
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class TemperatureSensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC temperature reporting sensor."""
|
||||
class SHCSensor(SHCEntity, SensorEntity):
|
||||
"""Representation of a SHC sensor."""
|
||||
|
||||
_attr_device_class = SensorDeviceClass.TEMPERATURE
|
||||
_attr_state_class = SensorStateClass.MEASUREMENT
|
||||
_attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS
|
||||
entity_description: SHCSensorEntityDescription
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC temperature reporting sensor."""
|
||||
def __init__(
|
||||
self,
|
||||
device: SHCDevice,
|
||||
entity_description: SHCSensorEntityDescription,
|
||||
parent_id: str,
|
||||
entry_id: str,
|
||||
) -> None:
|
||||
"""Initialize sensor."""
|
||||
super().__init__(device, parent_id, entry_id)
|
||||
self._attr_unique_id = f"{device.serial}_temperature"
|
||||
self.entity_description = entity_description
|
||||
self._attr_unique_id = f"{device.serial}_{entity_description.key}"
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.temperature
|
||||
|
||||
|
||||
class HumiditySensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC humidity reporting sensor."""
|
||||
|
||||
_attr_device_class = SensorDeviceClass.HUMIDITY
|
||||
_attr_native_unit_of_measurement = PERCENTAGE
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC humidity reporting sensor."""
|
||||
super().__init__(device, parent_id, entry_id)
|
||||
self._attr_unique_id = f"{device.serial}_humidity"
|
||||
return self.entity_description.value_fn(self._device)
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.humidity
|
||||
|
||||
|
||||
class PuritySensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC purity reporting sensor."""
|
||||
|
||||
_attr_translation_key = "purity"
|
||||
_attr_native_unit_of_measurement = CONCENTRATION_PARTS_PER_MILLION
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC purity reporting sensor."""
|
||||
super().__init__(device, parent_id, entry_id)
|
||||
self._attr_unique_id = f"{device.serial}_purity"
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.purity
|
||||
|
||||
|
||||
class AirQualitySensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC airquality reporting sensor."""
|
||||
|
||||
_attr_translation_key = "air_quality"
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC airquality reporting sensor."""
|
||||
super().__init__(device, parent_id, entry_id)
|
||||
self._attr_unique_id = f"{device.serial}_airquality"
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.combined_rating.name
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
def extra_state_attributes(self) -> dict[str, Any] | None:
|
||||
"""Return the state attributes."""
|
||||
return {
|
||||
"rating_description": self._device.description,
|
||||
}
|
||||
|
||||
|
||||
class TemperatureRatingSensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC temperature rating sensor."""
|
||||
|
||||
_attr_translation_key = "temperature_rating"
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC temperature rating sensor."""
|
||||
super().__init__(device, parent_id, entry_id)
|
||||
self._attr_unique_id = f"{device.serial}_temperature_rating"
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.temperature_rating.name
|
||||
|
||||
|
||||
class CommunicationQualitySensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC communication quality reporting sensor."""
|
||||
|
||||
_attr_translation_key = "communication_quality"
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC communication quality reporting sensor."""
|
||||
super().__init__(device, parent_id, entry_id)
|
||||
self._attr_unique_id = f"{device.serial}_communication_quality"
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.communicationquality.name
|
||||
|
||||
|
||||
class HumidityRatingSensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC humidity rating sensor."""
|
||||
|
||||
_attr_translation_key = "humidity_rating"
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC humidity rating sensor."""
|
||||
super().__init__(device, parent_id, entry_id)
|
||||
self._attr_unique_id = f"{device.serial}_humidity_rating"
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.humidity_rating.name
|
||||
|
||||
|
||||
class PurityRatingSensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC purity rating sensor."""
|
||||
|
||||
_attr_translation_key = "purity_rating"
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC purity rating sensor."""
|
||||
super().__init__(device, parent_id, entry_id)
|
||||
self._attr_unique_id = f"{device.serial}_purity_rating"
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.purity_rating.name
|
||||
|
||||
|
||||
class PowerSensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC power reporting sensor."""
|
||||
|
||||
_attr_device_class = SensorDeviceClass.POWER
|
||||
_attr_native_unit_of_measurement = UnitOfPower.WATT
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC power reporting sensor."""
|
||||
super().__init__(device, parent_id, entry_id)
|
||||
self._attr_unique_id = f"{device.serial}_power"
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.powerconsumption
|
||||
|
||||
|
||||
class EnergySensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC energy reporting sensor."""
|
||||
|
||||
_attr_device_class = SensorDeviceClass.ENERGY
|
||||
_attr_state_class = SensorStateClass.TOTAL_INCREASING
|
||||
_attr_native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC energy reporting sensor."""
|
||||
super().__init__(device, parent_id, entry_id)
|
||||
self._attr_unique_id = f"{self._device.serial}_energy"
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.energyconsumption / 1000.0
|
||||
|
||||
|
||||
class ValveTappetSensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC valve tappet reporting sensor."""
|
||||
|
||||
_attr_translation_key = "valvetappet"
|
||||
_attr_state_class = SensorStateClass.MEASUREMENT
|
||||
_attr_native_unit_of_measurement = PERCENTAGE
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC valve tappet reporting sensor."""
|
||||
super().__init__(device, parent_id, entry_id)
|
||||
self._attr_unique_id = f"{device.serial}_valvetappet"
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.position
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return the state attributes."""
|
||||
return {
|
||||
"valve_tappet_state": self._device.valvestate.name,
|
||||
}
|
||||
if self.entity_description.attributes_fn is not None:
|
||||
return self.entity_description.attributes_fn(self._device)
|
||||
return None
|
||||
|
|
Loading…
Add table
Reference in a new issue