Refactor mysensors sensor description (#54522)

Co-authored-by: Joakim Sørensen <joasoe@gmail.com>
pull/54705/head
Martin Hjelmare 2021-08-16 16:34:22 +02:00 committed by GitHub
parent 512a474e93
commit 494fd21351
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 165 additions and 105 deletions

View File

@ -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