Add sensors for energy storage system to ViCare integration (#106600)
* add sensors for vitocharge * add further sensors * add unig getters * remove icons * Update strings.json * handle percent uom * handle unknown uom device class mapping * add device class to sensor * add sensor options * Apply suggestions from code review * fix * align sensor naming * add feed-in and consumption sensors for pcc * Update strings.json * battery symbol * fix format * remove obsolete device classes * add icons * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * refactor * modify lambda * use helper * Apply suggestions from code review * Apply suggestions from code review * Update strings.json * Update sensor.py * Apply suggestions from code review Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>pull/110498/head^2
parent
4a128f1225
commit
1e564f777e
|
@ -1,7 +1,7 @@
|
|||
"""Constants for the ViCare integration."""
|
||||
import enum
|
||||
|
||||
from homeassistant.const import Platform, UnitOfEnergy, UnitOfVolume
|
||||
from homeassistant.const import Platform
|
||||
|
||||
DOMAIN = "vicare"
|
||||
|
||||
|
@ -22,14 +22,12 @@ CONF_HEATING_TYPE = "heating_type"
|
|||
|
||||
DEFAULT_CACHE_DURATION = 60
|
||||
|
||||
VICARE_CUBIC_METER = "cubicMeter"
|
||||
VICARE_PERCENT = "percent"
|
||||
VICARE_W = "watt"
|
||||
VICARE_KW = "kilowatt"
|
||||
VICARE_WH = "wattHour"
|
||||
VICARE_KWH = "kilowattHour"
|
||||
|
||||
|
||||
VICARE_UNIT_TO_UNIT_OF_MEASUREMENT = {
|
||||
VICARE_KWH: UnitOfEnergy.KILO_WATT_HOUR,
|
||||
VICARE_CUBIC_METER: UnitOfVolume.CUBIC_METERS,
|
||||
}
|
||||
VICARE_CUBIC_METER = "cubicMeter"
|
||||
|
||||
|
||||
class HeatingType(enum.Enum):
|
||||
|
|
|
@ -42,8 +42,11 @@ from .const import (
|
|||
DEVICE_LIST,
|
||||
DOMAIN,
|
||||
VICARE_CUBIC_METER,
|
||||
VICARE_KW,
|
||||
VICARE_KWH,
|
||||
VICARE_UNIT_TO_UNIT_OF_MEASUREMENT,
|
||||
VICARE_PERCENT,
|
||||
VICARE_W,
|
||||
VICARE_WH,
|
||||
)
|
||||
from .entity import ViCareEntity
|
||||
from .types import ViCareDevice, ViCareRequiredKeysMixin
|
||||
|
@ -52,10 +55,22 @@ from .utils import get_burners, get_circuits, get_compressors, is_supported
|
|||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
VICARE_UNIT_TO_DEVICE_CLASS = {
|
||||
VICARE_WH: SensorDeviceClass.ENERGY,
|
||||
VICARE_KWH: SensorDeviceClass.ENERGY,
|
||||
VICARE_W: SensorDeviceClass.POWER,
|
||||
VICARE_KW: SensorDeviceClass.POWER,
|
||||
VICARE_CUBIC_METER: SensorDeviceClass.GAS,
|
||||
}
|
||||
|
||||
VICARE_UNIT_TO_HA_UNIT = {
|
||||
VICARE_PERCENT: PERCENTAGE,
|
||||
VICARE_W: UnitOfPower.WATT,
|
||||
VICARE_KW: UnitOfPower.KILO_WATT,
|
||||
VICARE_WH: UnitOfEnergy.WATT_HOUR,
|
||||
VICARE_KWH: UnitOfEnergy.KILO_WATT_HOUR,
|
||||
VICARE_CUBIC_METER: UnitOfVolume.CUBIC_METERS,
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ViCareSensorEntityDescription(SensorEntityDescription, ViCareRequiredKeysMixin):
|
||||
|
@ -581,8 +596,83 @@ GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
|
|||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
ViCareSensorEntityDescription(
|
||||
key="ess_state_of_charge",
|
||||
icon="mdi:home-battery",
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
device_class=SensorDeviceClass.BATTERY,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_getter=lambda api: api.getElectricalEnergySystemSOC(),
|
||||
unit_getter=lambda api: api.getElectricalEnergySystemSOCUnit(),
|
||||
),
|
||||
ViCareSensorEntityDescription(
|
||||
key="ess_power_current",
|
||||
translation_key="ess_power_current",
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_getter=lambda api: api.getElectricalEnergySystemPower(),
|
||||
unit_getter=lambda api: api.getElectricalEnergySystemPowerUnit(),
|
||||
),
|
||||
ViCareSensorEntityDescription(
|
||||
key="ess_state",
|
||||
translation_key="ess_state",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
options=["charge", "discharge", "standby"],
|
||||
value_getter=lambda api: api.getElectricalEnergySystemOperationState(),
|
||||
),
|
||||
ViCareSensorEntityDescription(
|
||||
key="pcc_transfer_power_exchange",
|
||||
translation_key="pcc_transfer_power_exchange",
|
||||
icon="mdi:transmission-tower",
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_getter=lambda api: api.getPointOfCommonCouplingTransferPowerExchange(),
|
||||
),
|
||||
ViCareSensorEntityDescription(
|
||||
key="pcc_energy_consumption",
|
||||
translation_key="pcc_energy_consumption",
|
||||
icon="mdi:transmission-tower-export",
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
value_getter=lambda api: api.getPointOfCommonCouplingTransferConsumptionTotal(),
|
||||
unit_getter=lambda api: api.getPointOfCommonCouplingTransferConsumptionTotalUnit(),
|
||||
),
|
||||
ViCareSensorEntityDescription(
|
||||
key="pcc_energy_feed_in",
|
||||
translation_key="pcc_energy_feed_in",
|
||||
icon="mdi:transmission-tower-import",
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
value_getter=lambda api: api.getPointOfCommonCouplingTransferFeedInTotal(),
|
||||
unit_getter=lambda api: api.getPointOfCommonCouplingTransferFeedInTotalUnit(),
|
||||
),
|
||||
ViCareSensorEntityDescription(
|
||||
key="photovoltaic_power_production_current",
|
||||
translation_key="photovoltaic_power_production_current",
|
||||
native_unit_of_measurement=UnitOfPower.KILO_WATT,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_getter=lambda api: api.getPhotovoltaicProductionCurrent(),
|
||||
unit_getter=lambda api: api.getPhotovoltaicProductionCurrentUnit(),
|
||||
),
|
||||
ViCareSensorEntityDescription(
|
||||
key="photovoltaic_energy_production_today",
|
||||
translation_key="photovoltaic_energy_production_today",
|
||||
icon="mdi:solar-power",
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
value_getter=lambda api: api.getPhotovoltaicProductionCumulatedCurrentDay(),
|
||||
unit_getter=lambda api: api.getPhotovoltaicProductionCumulatedUnit(),
|
||||
),
|
||||
ViCareSensorEntityDescription(
|
||||
key="photovoltaic_status",
|
||||
translation_key="photovoltaic_status",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
options=["ready", "production"],
|
||||
value_getter=lambda api: _filter_pv_states(api.getPhotovoltaicStatus()),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
CIRCUIT_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
|
||||
ViCareSensorEntityDescription(
|
||||
key="supply_temperature",
|
||||
|
@ -700,6 +790,10 @@ COMPRESSOR_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
|
|||
)
|
||||
|
||||
|
||||
def _filter_pv_states(state: str) -> str | None:
|
||||
return None if state in ("nothing", "unknown") else state
|
||||
|
||||
|
||||
def _build_entities(
|
||||
device_list: list[ViCareDevice],
|
||||
) -> list[ViCareSensor]:
|
||||
|
@ -800,6 +894,7 @@ class ViCareSensor(ViCareEntity, SensorEntity):
|
|||
|
||||
def update(self) -> None:
|
||||
"""Update state of sensor."""
|
||||
vicare_unit = None
|
||||
try:
|
||||
with suppress(PyViCareNotSupportedFeatureError):
|
||||
self._attr_native_value = self.entity_description.value_getter(
|
||||
|
@ -808,13 +903,6 @@ class ViCareSensor(ViCareEntity, SensorEntity):
|
|||
|
||||
if self.entity_description.unit_getter:
|
||||
vicare_unit = self.entity_description.unit_getter(self._api)
|
||||
if vicare_unit is not None:
|
||||
self._attr_device_class = VICARE_UNIT_TO_DEVICE_CLASS.get(
|
||||
vicare_unit
|
||||
)
|
||||
self._attr_native_unit_of_measurement = (
|
||||
VICARE_UNIT_TO_UNIT_OF_MEASUREMENT.get(vicare_unit)
|
||||
)
|
||||
except requests.exceptions.ConnectionError:
|
||||
_LOGGER.error("Unable to retrieve data from ViCare server")
|
||||
except ValueError:
|
||||
|
@ -823,3 +911,12 @@ class ViCareSensor(ViCareEntity, SensorEntity):
|
|||
_LOGGER.error("Vicare API rate limit exceeded: %s", limit_exception)
|
||||
except PyViCareInvalidDataError as invalid_data_exception:
|
||||
_LOGGER.error("Invalid data from Vicare server: %s", invalid_data_exception)
|
||||
|
||||
if vicare_unit is not None:
|
||||
if (
|
||||
device_class := VICARE_UNIT_TO_DEVICE_CLASS.get(vicare_unit)
|
||||
) is not None:
|
||||
self._attr_device_class = device_class
|
||||
self._attr_native_unit_of_measurement = VICARE_UNIT_TO_HA_UNIT.get(
|
||||
vicare_unit
|
||||
)
|
||||
|
|
|
@ -275,6 +275,39 @@
|
|||
"volumetric_flow": {
|
||||
"name": "Volumetric flow"
|
||||
},
|
||||
"ess_power_current": {
|
||||
"name": "Battery power"
|
||||
},
|
||||
"ess_state": {
|
||||
"name": "Battery state",
|
||||
"state": {
|
||||
"charge": "Charging",
|
||||
"discharge": "Discharging",
|
||||
"standby": "Standby"
|
||||
}
|
||||
},
|
||||
"pcc_current_power_exchange": {
|
||||
"name": "Grid power exchange"
|
||||
},
|
||||
"pcc_energy_consumption": {
|
||||
"name": "Energy import from grid"
|
||||
},
|
||||
"pcc_energy_feed_in": {
|
||||
"name": "Energy export to grid"
|
||||
},
|
||||
"photovoltaic_power_production_current": {
|
||||
"name": "Solar power"
|
||||
},
|
||||
"photovoltaic_energy_production_today": {
|
||||
"name": "Solar energy production today"
|
||||
},
|
||||
"photovoltaic_status": {
|
||||
"name": "Solar state",
|
||||
"state": {
|
||||
"ready": "Standby",
|
||||
"production": "Producing"
|
||||
}
|
||||
},
|
||||
"supply_temperature": {
|
||||
"name": "Supply temperature"
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue