Add dynamic unit of measurement support for Overkiz sensor (#80490)

* Add dynamic unit support

* Import all units

* Fix typing

* Add fallback to CORE_ELECTRIC_POWER_CONSUMPTION_STATE_MEASURED_VALUE_TYPE

* Fix rebase

* Give priority to the more accurate attribute

* Don’t use hardcoded seconds unit

* Don’t change SensorDescription

* Rework comment
pull/88970/head
Thibaut 2023-03-01 13:46:26 +01:00 committed by GitHub
parent 85f2693353
commit 0c66346fb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 3 deletions

View File

@ -5,9 +5,28 @@ from datetime import timedelta
import logging
from typing import Final
from pyoverkiz.enums import OverkizCommandParam, UIClass, UIWidget
from pyoverkiz.enums import MeasuredValueType, OverkizCommandParam, UIClass, UIWidget
from homeassistant.const import Platform
from homeassistant.const import (
CONCENTRATION_PARTS_PER_BILLION,
CONCENTRATION_PARTS_PER_MILLION,
DEGREE,
LIGHT_LUX,
PERCENTAGE,
Platform,
UnitOfElectricCurrent,
UnitOfElectricPotential,
UnitOfEnergy,
UnitOfIrradiance,
UnitOfLength,
UnitOfPower,
UnitOfPressure,
UnitOfSpeed,
UnitOfTemperature,
UnitOfTime,
UnitOfVolume,
UnitOfVolumeFlowRate,
)
DOMAIN: Final = "overkiz"
LOGGER: logging.Logger = logging.getLogger(__package__)
@ -98,3 +117,42 @@ OVERKIZ_STATE_TO_TRANSLATION: dict[str, str] = {
OverkizCommandParam.SFC: "sfc",
OverkizCommandParam.UPS: "ups",
}
OVERKIZ_UNIT_TO_HA: dict[str, str] = {
MeasuredValueType.ABSOLUTE_VALUE: "",
MeasuredValueType.ANGLE_IN_DEGREES: DEGREE,
MeasuredValueType.ANGULAR_SPEED_IN_DEGREES_PER_SECOND: f"{DEGREE}/{UnitOfTime.SECONDS}",
MeasuredValueType.ELECTRICAL_ENERGY_IN_KWH: UnitOfEnergy.KILO_WATT_HOUR,
MeasuredValueType.ELECTRICAL_ENERGY_IN_WH: UnitOfEnergy.WATT_HOUR,
MeasuredValueType.ELECTRICAL_POWER_IN_KW: UnitOfPower.KILO_WATT,
MeasuredValueType.ELECTRICAL_POWER_IN_W: UnitOfPower.WATT,
MeasuredValueType.ELECTRIC_CURRENT_IN_AMPERE: UnitOfElectricCurrent.AMPERE,
MeasuredValueType.ELECTRIC_CURRENT_IN_MILLI_AMPERE: UnitOfElectricCurrent.MILLIAMPERE,
MeasuredValueType.ENERGY_IN_CAL: "cal",
MeasuredValueType.ENERGY_IN_KCAL: "kcal",
MeasuredValueType.FLOW_IN_LITRE_PER_SECOND: f"{UnitOfVolume.LITERS}/{UnitOfTime.SECONDS}",
MeasuredValueType.FLOW_IN_METER_CUBE_PER_HOUR: UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
MeasuredValueType.FLOW_IN_METER_CUBE_PER_SECOND: f"{UnitOfVolume.CUBIC_METERS}/{UnitOfTime.SECONDS}",
MeasuredValueType.FOSSIL_ENERGY_IN_WH: UnitOfEnergy.WATT_HOUR,
MeasuredValueType.GRADIENT_IN_PERCENTAGE_PER_SECOND: f"{PERCENTAGE}/{UnitOfTime.SECONDS}",
MeasuredValueType.LENGTH_IN_METER: UnitOfLength.METERS,
MeasuredValueType.LINEAR_SPEED_IN_METER_PER_SECOND: UnitOfSpeed.METERS_PER_SECOND,
MeasuredValueType.LUMINANCE_IN_LUX: LIGHT_LUX,
MeasuredValueType.PARTS_PER_BILLION: CONCENTRATION_PARTS_PER_BILLION,
MeasuredValueType.PARTS_PER_MILLION: CONCENTRATION_PARTS_PER_MILLION,
MeasuredValueType.PARTS_PER_QUADRILLION: "ppq",
MeasuredValueType.PARTS_PER_TRILLION: "ppt",
MeasuredValueType.POWER_PER_SQUARE_METER: UnitOfIrradiance.WATTS_PER_SQUARE_METER,
MeasuredValueType.PRESSURE_IN_HPA: UnitOfPressure.HPA,
MeasuredValueType.PRESSURE_IN_MILLI_BAR: UnitOfPressure.MBAR,
MeasuredValueType.RELATIVE_VALUE_IN_PERCENTAGE: PERCENTAGE,
MeasuredValueType.TEMPERATURE_IN_CELCIUS: UnitOfTemperature.CELSIUS,
MeasuredValueType.TEMPERATURE_IN_KELVIN: UnitOfTemperature.KELVIN,
MeasuredValueType.TIME_IN_SECOND: UnitOfTime.SECONDS,
# MeasuredValueType.VECTOR_COORDINATE: "",
MeasuredValueType.VOLTAGE_IN_MILLI_VOLT: UnitOfElectricPotential.MILLIVOLT,
MeasuredValueType.VOLTAGE_IN_VOLT: UnitOfElectricPotential.VOLT,
MeasuredValueType.VOLUME_IN_CUBIC_METER: UnitOfVolume.CUBIC_METERS,
MeasuredValueType.VOLUME_IN_GALLON: UnitOfVolume.GALLONS,
MeasuredValueType.VOLUME_IN_LITER: UnitOfVolume.LITERS,
}

View File

@ -34,7 +34,12 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from . import HomeAssistantOverkizData
from .const import DOMAIN, IGNORED_OVERKIZ_DEVICES, OVERKIZ_STATE_TO_TRANSLATION
from .const import (
DOMAIN,
IGNORED_OVERKIZ_DEVICES,
OVERKIZ_STATE_TO_TRANSLATION,
OVERKIZ_UNIT_TO_HA,
)
from .coordinator import OverkizDataUpdateCoordinator
from .entity import OverkizDescriptiveEntity, OverkizEntity
@ -473,6 +478,29 @@ class OverkizStateSensor(OverkizDescriptiveEntity, SensorEntity):
return state.value
@property
def native_unit_of_measurement(self) -> str | None:
"""Return the unit of measurement."""
if (
not (default_unit := self.entity_description.native_unit_of_measurement)
or not (state := self.device.states.get(self.entity_description.key))
or not state.value
):
return default_unit
attrs = self.device.attributes
if (unit := attrs[f"{state.name}MeasuredValueType"]) and (
unit_value := unit.value_as_str
):
return OVERKIZ_UNIT_TO_HA.get(unit_value, default_unit)
if (unit := attrs[OverkizAttribute.CORE_MEASURED_VALUE_TYPE]) and (
unit_value := unit.value_as_str
):
return OVERKIZ_UNIT_TO_HA.get(unit_value, default_unit)
return default_unit
class OverkizHomeKitSetupCodeSensor(OverkizEntity, SensorEntity):
"""Representation of an Overkiz HomeKit Setup Code."""