Support native_precision
in Airly integration (#86843)
* Use native_precision * Refactor extra_state_attributes
This commit is contained in:
parent
58de7b8df0
commit
eebc338c3b
1 changed files with 53 additions and 65 deletions
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, cast
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
|
@ -19,11 +19,10 @@ from homeassistant.const import (
|
|||
UnitOfPressure,
|
||||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.device_registry import DeviceEntryType
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from . import AirlyDataUpdateCoordinator
|
||||
|
@ -62,7 +61,7 @@ PARALLEL_UPDATES = 1
|
|||
class AirlySensorEntityDescription(SensorEntityDescription):
|
||||
"""Class describing Airly sensor entities."""
|
||||
|
||||
value: Callable = round
|
||||
attrs: Callable[[dict[str, Any]], dict[str, Any]] = lambda data: {}
|
||||
|
||||
|
||||
SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
|
||||
|
@ -70,12 +69,19 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
|
|||
key=ATTR_API_CAQI,
|
||||
icon="mdi:air-filter",
|
||||
name=ATTR_API_CAQI,
|
||||
native_precision=0,
|
||||
native_unit_of_measurement="CAQI",
|
||||
attrs=lambda data: {
|
||||
ATTR_LEVEL: data[ATTR_API_CAQI_LEVEL],
|
||||
ATTR_ADVICE: data[ATTR_API_ADVICE],
|
||||
ATTR_DESCRIPTION: data[ATTR_API_CAQI_DESCRIPTION],
|
||||
},
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_PM1,
|
||||
device_class=SensorDeviceClass.PM1,
|
||||
name=ATTR_API_PM1,
|
||||
native_precision=0,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
|
@ -83,28 +89,39 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
|
|||
key=ATTR_API_PM25,
|
||||
device_class=SensorDeviceClass.PM25,
|
||||
name="PM2.5",
|
||||
native_precision=0,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
attrs=lambda data: {
|
||||
ATTR_LIMIT: data[f"{ATTR_API_PM25}_{SUFFIX_LIMIT}"],
|
||||
ATTR_PERCENT: round(data[f"{ATTR_API_PM25}_{SUFFIX_PERCENT}"]),
|
||||
},
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_PM10,
|
||||
device_class=SensorDeviceClass.PM10,
|
||||
name=ATTR_API_PM10,
|
||||
native_precision=0,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
attrs=lambda data: {
|
||||
ATTR_LIMIT: data[f"{ATTR_API_PM10}_{SUFFIX_LIMIT}"],
|
||||
ATTR_PERCENT: round(data[f"{ATTR_API_PM10}_{SUFFIX_PERCENT}"]),
|
||||
},
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_HUMIDITY,
|
||||
device_class=SensorDeviceClass.HUMIDITY,
|
||||
name=ATTR_API_HUMIDITY.capitalize(),
|
||||
native_precision=1,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value=lambda value: round(value, 1),
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_PRESSURE,
|
||||
device_class=SensorDeviceClass.PRESSURE,
|
||||
name=ATTR_API_PRESSURE.capitalize(),
|
||||
native_precision=0,
|
||||
native_unit_of_measurement=UnitOfPressure.HPA,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
|
@ -112,36 +129,56 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
|
|||
key=ATTR_API_TEMPERATURE,
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
name=ATTR_API_TEMPERATURE.capitalize(),
|
||||
native_precision=1,
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value=lambda value: round(value, 1),
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_CO,
|
||||
name=ATTR_API_CO,
|
||||
native_precision=0,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
attrs=lambda data: {
|
||||
ATTR_LIMIT: data[f"{ATTR_API_CO}_{SUFFIX_LIMIT}"],
|
||||
ATTR_PERCENT: round(data[f"{ATTR_API_CO}_{SUFFIX_PERCENT}"]),
|
||||
},
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_NO2,
|
||||
device_class=SensorDeviceClass.NITROGEN_DIOXIDE,
|
||||
name=ATTR_API_NO2,
|
||||
native_precision=0,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
attrs=lambda data: {
|
||||
ATTR_LIMIT: data[f"{ATTR_API_NO2}_{SUFFIX_LIMIT}"],
|
||||
ATTR_PERCENT: round(data[f"{ATTR_API_NO2}_{SUFFIX_PERCENT}"]),
|
||||
},
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_SO2,
|
||||
device_class=SensorDeviceClass.SULPHUR_DIOXIDE,
|
||||
name=ATTR_API_SO2,
|
||||
native_precision=0,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
attrs=lambda data: {
|
||||
ATTR_LIMIT: data[f"{ATTR_API_SO2}_{SUFFIX_LIMIT}"],
|
||||
ATTR_PERCENT: round(data[f"{ATTR_API_SO2}_{SUFFIX_PERCENT}"]),
|
||||
},
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_O3,
|
||||
device_class=SensorDeviceClass.OZONE,
|
||||
name=ATTR_API_O3,
|
||||
native_precision=0,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
attrs=lambda data: {
|
||||
ATTR_LIMIT: data[f"{ATTR_API_O3}_{SUFFIX_LIMIT}"],
|
||||
ATTR_PERCENT: round(data[f"{ATTR_API_O3}_{SUFFIX_PERCENT}"]),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -190,64 +227,15 @@ class AirlySensor(CoordinatorEntity[AirlyDataUpdateCoordinator], SensorEntity):
|
|||
self._attr_unique_id = (
|
||||
f"{coordinator.latitude}-{coordinator.longitude}-{description.key}".lower()
|
||||
)
|
||||
self._attrs: dict[str, Any] = {}
|
||||
self._attr_native_value = coordinator.data[description.key]
|
||||
self._attr_extra_state_attributes = description.attrs(coordinator.data)
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state."""
|
||||
state = self.coordinator.data[self.entity_description.key]
|
||||
return cast(StateType, self.entity_description.value(state))
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return the state attributes."""
|
||||
if self.entity_description.key == ATTR_API_CAQI:
|
||||
self._attrs[ATTR_LEVEL] = self.coordinator.data[ATTR_API_CAQI_LEVEL]
|
||||
self._attrs[ATTR_ADVICE] = self.coordinator.data[ATTR_API_ADVICE]
|
||||
self._attrs[ATTR_DESCRIPTION] = self.coordinator.data[
|
||||
ATTR_API_CAQI_DESCRIPTION
|
||||
]
|
||||
if self.entity_description.key == ATTR_API_PM25:
|
||||
self._attrs[ATTR_LIMIT] = self.coordinator.data[
|
||||
f"{ATTR_API_PM25}_{SUFFIX_LIMIT}"
|
||||
]
|
||||
self._attrs[ATTR_PERCENT] = round(
|
||||
self.coordinator.data[f"{ATTR_API_PM25}_{SUFFIX_PERCENT}"]
|
||||
)
|
||||
if self.entity_description.key == ATTR_API_PM10:
|
||||
self._attrs[ATTR_LIMIT] = self.coordinator.data[
|
||||
f"{ATTR_API_PM10}_{SUFFIX_LIMIT}"
|
||||
]
|
||||
self._attrs[ATTR_PERCENT] = round(
|
||||
self.coordinator.data[f"{ATTR_API_PM10}_{SUFFIX_PERCENT}"]
|
||||
)
|
||||
if self.entity_description.key == ATTR_API_CO:
|
||||
self._attrs[ATTR_LIMIT] = self.coordinator.data[
|
||||
f"{ATTR_API_CO}_{SUFFIX_LIMIT}"
|
||||
]
|
||||
self._attrs[ATTR_PERCENT] = round(
|
||||
self.coordinator.data[f"{ATTR_API_CO}_{SUFFIX_PERCENT}"]
|
||||
)
|
||||
if self.entity_description.key == ATTR_API_NO2:
|
||||
self._attrs[ATTR_LIMIT] = self.coordinator.data[
|
||||
f"{ATTR_API_NO2}_{SUFFIX_LIMIT}"
|
||||
]
|
||||
self._attrs[ATTR_PERCENT] = round(
|
||||
self.coordinator.data[f"{ATTR_API_NO2}_{SUFFIX_PERCENT}"]
|
||||
)
|
||||
if self.entity_description.key == ATTR_API_SO2:
|
||||
self._attrs[ATTR_LIMIT] = self.coordinator.data[
|
||||
f"{ATTR_API_SO2}_{SUFFIX_LIMIT}"
|
||||
]
|
||||
self._attrs[ATTR_PERCENT] = round(
|
||||
self.coordinator.data[f"{ATTR_API_SO2}_{SUFFIX_PERCENT}"]
|
||||
)
|
||||
if self.entity_description.key == ATTR_API_O3:
|
||||
self._attrs[ATTR_LIMIT] = self.coordinator.data[
|
||||
f"{ATTR_API_O3}_{SUFFIX_LIMIT}"
|
||||
]
|
||||
self._attrs[ATTR_PERCENT] = round(
|
||||
self.coordinator.data[f"{ATTR_API_O3}_{SUFFIX_PERCENT}"]
|
||||
)
|
||||
return self._attrs
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
self._attr_native_value = self.coordinator.data[self.entity_description.key]
|
||||
self._attr_extra_state_attributes = self.entity_description.attrs(
|
||||
self.coordinator.data
|
||||
)
|
||||
self.async_write_ha_state()
|
||||
|
|
Loading…
Add table
Reference in a new issue