Refactor mysensors sensor description (#54522)
Co-authored-by: Joakim Sørensen <joasoe@gmail.com>pull/54705/head
parent
512a474e93
commit
494fd21351
|
@ -1,7 +1,7 @@
|
|||
"""Support for MySensors sensors."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from awesomeversion import AwesomeVersion
|
||||
|
||||
|
@ -10,6 +10,7 @@ from homeassistant.components.sensor import (
|
|||
DOMAIN,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
SensorEntity,
|
||||
SensorEntityDescription,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
|
@ -46,64 +47,150 @@ from homeassistant.util.dt import utc_from_timestamp
|
|||
from .const import MYSENSORS_DISCOVERY, DiscoveryInfo
|
||||
from .helpers import on_unload
|
||||
|
||||
SENSORS: dict[str, list[str | None] | dict[str, list[str | None]]] = {
|
||||
"V_TEMP": [None, None, DEVICE_CLASS_TEMPERATURE, STATE_CLASS_MEASUREMENT],
|
||||
"V_HUM": [
|
||||
PERCENTAGE,
|
||||
"mdi:water-percent",
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
],
|
||||
"V_DIMMER": [PERCENTAGE, "mdi:percent", None, None],
|
||||
"V_PERCENTAGE": [PERCENTAGE, "mdi:percent", None, None],
|
||||
"V_PRESSURE": [None, "mdi:gauge", None, None],
|
||||
"V_FORECAST": [None, "mdi:weather-partly-cloudy", None, None],
|
||||
"V_RAIN": [None, "mdi:weather-rainy", None, None],
|
||||
"V_RAINRATE": [None, "mdi:weather-rainy", None, None],
|
||||
"V_WIND": [None, "mdi:weather-windy", None, None],
|
||||
"V_GUST": [None, "mdi:weather-windy", None, None],
|
||||
"V_DIRECTION": [DEGREE, "mdi:compass", None, None],
|
||||
"V_WEIGHT": [MASS_KILOGRAMS, "mdi:weight-kilogram", None, None],
|
||||
"V_DISTANCE": [LENGTH_METERS, "mdi:ruler", None, None],
|
||||
"V_IMPEDANCE": ["ohm", None, None, None],
|
||||
"V_WATT": [POWER_WATT, None, DEVICE_CLASS_POWER, STATE_CLASS_MEASUREMENT],
|
||||
"V_KWH": [
|
||||
ENERGY_KILO_WATT_HOUR,
|
||||
None,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
],
|
||||
"V_LIGHT_LEVEL": [PERCENTAGE, "mdi:white-balance-sunny", None, None],
|
||||
"V_FLOW": [LENGTH_METERS, "mdi:gauge", None, None],
|
||||
"V_VOLUME": [VOLUME_CUBIC_METERS, None, None, None],
|
||||
"V_LEVEL": {
|
||||
"S_SOUND": [SOUND_PRESSURE_DB, "mdi:volume-high", None, None],
|
||||
"S_VIBRATION": [FREQUENCY_HERTZ, None, None, None],
|
||||
"S_LIGHT_LEVEL": [
|
||||
LIGHT_LUX,
|
||||
"mdi:white-balance-sunny",
|
||||
DEVICE_CLASS_ILLUMINANCE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
],
|
||||
"S_MOISTURE": [PERCENTAGE, "mdi:water-percent", None, None],
|
||||
},
|
||||
"V_VOLTAGE": [
|
||||
ELECTRIC_POTENTIAL_VOLT,
|
||||
"mdi:flash",
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
],
|
||||
"V_CURRENT": [
|
||||
ELECTRIC_CURRENT_AMPERE,
|
||||
"mdi:flash-auto",
|
||||
DEVICE_CLASS_CURRENT,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
],
|
||||
"V_PH": ["pH", None, None, None],
|
||||
"V_ORP": [ELECTRIC_POTENTIAL_MILLIVOLT, None, None, None],
|
||||
"V_EC": [CONDUCTIVITY, None, None, None],
|
||||
"V_VAR": ["var", None, None, None],
|
||||
"V_VA": [POWER_VOLT_AMPERE, None, None, None],
|
||||
SENSORS: dict[str, SensorEntityDescription] = {
|
||||
"V_TEMP": SensorEntityDescription(
|
||||
key="V_TEMP",
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
"V_HUM": SensorEntityDescription(
|
||||
key="V_HUM",
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
device_class=DEVICE_CLASS_HUMIDITY,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
"V_DIMMER": SensorEntityDescription(
|
||||
key="V_DIMMER",
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
),
|
||||
"V_PERCENTAGE": SensorEntityDescription(
|
||||
key="V_PERCENTAGE",
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
),
|
||||
"V_PRESSURE": SensorEntityDescription(
|
||||
key="V_PRESSURE",
|
||||
icon="mdi:gauge",
|
||||
),
|
||||
"V_FORECAST": SensorEntityDescription(
|
||||
key="V_FORECAST",
|
||||
icon="mdi:weather-partly-cloudy",
|
||||
),
|
||||
"V_RAIN": SensorEntityDescription(
|
||||
key="V_RAIN",
|
||||
icon="mdi:weather-rainy",
|
||||
),
|
||||
"V_RAINRATE": SensorEntityDescription(
|
||||
key="V_RAINRATE",
|
||||
icon="mdi:weather-rainy",
|
||||
),
|
||||
"V_WIND": SensorEntityDescription(
|
||||
key="V_WIND",
|
||||
icon="mdi:weather-windy",
|
||||
),
|
||||
"V_GUST": SensorEntityDescription(
|
||||
key="V_GUST",
|
||||
icon="mdi:weather-windy",
|
||||
),
|
||||
"V_DIRECTION": SensorEntityDescription(
|
||||
key="V_DIRECTION",
|
||||
native_unit_of_measurement=DEGREE,
|
||||
icon="mdi:compass",
|
||||
),
|
||||
"V_WEIGHT": SensorEntityDescription(
|
||||
key="V_WEIGHT",
|
||||
native_unit_of_measurement=MASS_KILOGRAMS,
|
||||
icon="mdi:weight-kilogram",
|
||||
),
|
||||
"V_DISTANCE": SensorEntityDescription(
|
||||
key="V_DISTANCE",
|
||||
native_unit_of_measurement=LENGTH_METERS,
|
||||
icon="mdi:ruler",
|
||||
),
|
||||
"V_IMPEDANCE": SensorEntityDescription(
|
||||
key="V_IMPEDANCE",
|
||||
native_unit_of_measurement="ohm",
|
||||
),
|
||||
"V_WATT": SensorEntityDescription(
|
||||
key="V_WATT",
|
||||
native_unit_of_measurement=POWER_WATT,
|
||||
device_class=DEVICE_CLASS_POWER,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
"V_KWH": SensorEntityDescription(
|
||||
key="V_KWH",
|
||||
native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
|
||||
device_class=DEVICE_CLASS_ENERGY,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
last_reset=utc_from_timestamp(0),
|
||||
),
|
||||
"V_LIGHT_LEVEL": SensorEntityDescription(
|
||||
key="V_LIGHT_LEVEL",
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:white-balance-sunny",
|
||||
),
|
||||
"V_FLOW": SensorEntityDescription(
|
||||
key="V_FLOW",
|
||||
native_unit_of_measurement=LENGTH_METERS,
|
||||
icon="mdi:gauge",
|
||||
),
|
||||
"V_VOLUME": SensorEntityDescription(
|
||||
key="V_VOLUME",
|
||||
native_unit_of_measurement=VOLUME_CUBIC_METERS,
|
||||
),
|
||||
"V_LEVEL_S_SOUND": SensorEntityDescription(
|
||||
key="V_LEVEL_S_SOUND",
|
||||
native_unit_of_measurement=SOUND_PRESSURE_DB,
|
||||
icon="mdi:volume-high",
|
||||
),
|
||||
"V_LEVEL_S_VIBRATION": SensorEntityDescription(
|
||||
key="V_LEVEL_S_VIBRATION",
|
||||
native_unit_of_measurement=FREQUENCY_HERTZ,
|
||||
),
|
||||
"V_LEVEL_S_LIGHT_LEVEL": SensorEntityDescription(
|
||||
key="V_LEVEL_S_LIGHT_LEVEL",
|
||||
native_unit_of_measurement=LIGHT_LUX,
|
||||
device_class=DEVICE_CLASS_ILLUMINANCE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
"V_LEVEL_S_MOISTURE": SensorEntityDescription(
|
||||
key="V_LEVEL_S_MOISTURE",
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:water-percent",
|
||||
),
|
||||
"V_VOLTAGE": SensorEntityDescription(
|
||||
key="V_VOLTAGE",
|
||||
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
|
||||
device_class=DEVICE_CLASS_VOLTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
"V_CURRENT": SensorEntityDescription(
|
||||
key="V_CURRENT",
|
||||
native_unit_of_measurement=ELECTRIC_CURRENT_AMPERE,
|
||||
device_class=DEVICE_CLASS_CURRENT,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
"V_PH": SensorEntityDescription(
|
||||
key="V_PH",
|
||||
native_unit_of_measurement="pH",
|
||||
),
|
||||
"V_ORP": SensorEntityDescription(
|
||||
key="V_ORP",
|
||||
native_unit_of_measurement=ELECTRIC_POTENTIAL_MILLIVOLT,
|
||||
),
|
||||
"V_EC": SensorEntityDescription(
|
||||
key="V_EC",
|
||||
native_unit_of_measurement=CONDUCTIVITY,
|
||||
),
|
||||
"V_VAR": SensorEntityDescription(
|
||||
key="V_VAR",
|
||||
native_unit_of_measurement="var",
|
||||
),
|
||||
"V_VA": SensorEntityDescription(
|
||||
key="V_VA",
|
||||
native_unit_of_measurement=POWER_VOLT_AMPERE,
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
|
@ -138,44 +225,19 @@ async def async_setup_entry(
|
|||
class MySensorsSensor(mysensors.device.MySensorsEntity, SensorEntity):
|
||||
"""Representation of a MySensors Sensor child node."""
|
||||
|
||||
@property
|
||||
def force_update(self) -> bool:
|
||||
"""Return True if state updates should be forced.
|
||||
_attr_force_update = True
|
||||
|
||||
If True, a state change will be triggered anytime the state property is
|
||||
updated, not just when the value changes.
|
||||
"""
|
||||
return True
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
"""Set up the instance."""
|
||||
super().__init__(*args, **kwargs)
|
||||
if entity_description := self._get_entity_description():
|
||||
self.entity_description = entity_description
|
||||
|
||||
@property
|
||||
def native_value(self) -> str | None:
|
||||
"""Return the state of the device."""
|
||||
"""Return the state of the sensor."""
|
||||
return self._values.get(self.value_type)
|
||||
|
||||
@property
|
||||
def device_class(self) -> str | None:
|
||||
"""Return the device class of this entity."""
|
||||
return self._get_sensor_type()[2]
|
||||
|
||||
@property
|
||||
def icon(self) -> str | None:
|
||||
"""Return the icon to use in the frontend, if any."""
|
||||
return self._get_sensor_type()[1]
|
||||
|
||||
@property
|
||||
def last_reset(self) -> datetime | None:
|
||||
"""Return the time when the sensor was last reset, if any."""
|
||||
set_req = self.gateway.const.SetReq
|
||||
|
||||
if set_req(self.value_type).name == "V_KWH":
|
||||
return utc_from_timestamp(0)
|
||||
return None
|
||||
|
||||
@property
|
||||
def state_class(self) -> str | None:
|
||||
"""Return the state class of this entity."""
|
||||
return self._get_sensor_type()[3]
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return the unit of measurement of this entity."""
|
||||
|
@ -192,21 +254,19 @@ class MySensorsSensor(mysensors.device.MySensorsEntity, SensorEntity):
|
|||
return TEMP_CELSIUS
|
||||
return TEMP_FAHRENHEIT
|
||||
|
||||
unit = self._get_sensor_type()[0]
|
||||
return unit
|
||||
if hasattr(self, "entity_description"):
|
||||
return self.entity_description.native_unit_of_measurement
|
||||
return None
|
||||
|
||||
def _get_sensor_type(self) -> list[str | None]:
|
||||
"""Return list with unit and icon of sensor type."""
|
||||
pres = self.gateway.const.Presentation
|
||||
def _get_entity_description(self) -> SensorEntityDescription | None:
|
||||
"""Return the sensor entity description."""
|
||||
set_req = self.gateway.const.SetReq
|
||||
entity_description = SENSORS.get(set_req(self.value_type).name)
|
||||
|
||||
_sensor_type = SENSORS.get(
|
||||
set_req(self.value_type).name, [None, None, None, None]
|
||||
)
|
||||
if isinstance(_sensor_type, dict):
|
||||
sensor_type = _sensor_type.get(
|
||||
pres(self.child_type).name, [None, None, None, None]
|
||||
if not entity_description:
|
||||
pres = self.gateway.const.Presentation
|
||||
entity_description = SENSORS.get(
|
||||
f"{set_req(self.value_type).name}_{pres(self.child_type).name}"
|
||||
)
|
||||
else:
|
||||
sensor_type = _sensor_type
|
||||
return sensor_type
|
||||
|
||||
return entity_description
|
||||
|
|
Loading…
Reference in New Issue