mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 03:37:07 +00:00
Support native_precision
in Airly integration (#86843)
* Use native_precision * Refactor extra_state_attributes
This commit is contained in:
parent
58de7b8df0
commit
eebc338c3b
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Any, cast
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
SensorDeviceClass,
|
SensorDeviceClass,
|
||||||
@ -19,11 +19,10 @@ from homeassistant.const import (
|
|||||||
UnitOfPressure,
|
UnitOfPressure,
|
||||||
UnitOfTemperature,
|
UnitOfTemperature,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.device_registry import DeviceEntryType
|
from homeassistant.helpers.device_registry import DeviceEntryType
|
||||||
from homeassistant.helpers.entity import DeviceInfo
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.typing import StateType
|
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import AirlyDataUpdateCoordinator
|
from . import AirlyDataUpdateCoordinator
|
||||||
@ -62,7 +61,7 @@ PARALLEL_UPDATES = 1
|
|||||||
class AirlySensorEntityDescription(SensorEntityDescription):
|
class AirlySensorEntityDescription(SensorEntityDescription):
|
||||||
"""Class describing Airly sensor entities."""
|
"""Class describing Airly sensor entities."""
|
||||||
|
|
||||||
value: Callable = round
|
attrs: Callable[[dict[str, Any]], dict[str, Any]] = lambda data: {}
|
||||||
|
|
||||||
|
|
||||||
SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
|
SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
|
||||||
@ -70,12 +69,19 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
|
|||||||
key=ATTR_API_CAQI,
|
key=ATTR_API_CAQI,
|
||||||
icon="mdi:air-filter",
|
icon="mdi:air-filter",
|
||||||
name=ATTR_API_CAQI,
|
name=ATTR_API_CAQI,
|
||||||
|
native_precision=0,
|
||||||
native_unit_of_measurement="CAQI",
|
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(
|
AirlySensorEntityDescription(
|
||||||
key=ATTR_API_PM1,
|
key=ATTR_API_PM1,
|
||||||
device_class=SensorDeviceClass.PM1,
|
device_class=SensorDeviceClass.PM1,
|
||||||
name=ATTR_API_PM1,
|
name=ATTR_API_PM1,
|
||||||
|
native_precision=0,
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
@ -83,28 +89,39 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
|
|||||||
key=ATTR_API_PM25,
|
key=ATTR_API_PM25,
|
||||||
device_class=SensorDeviceClass.PM25,
|
device_class=SensorDeviceClass.PM25,
|
||||||
name="PM2.5",
|
name="PM2.5",
|
||||||
|
native_precision=0,
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
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(
|
AirlySensorEntityDescription(
|
||||||
key=ATTR_API_PM10,
|
key=ATTR_API_PM10,
|
||||||
device_class=SensorDeviceClass.PM10,
|
device_class=SensorDeviceClass.PM10,
|
||||||
name=ATTR_API_PM10,
|
name=ATTR_API_PM10,
|
||||||
|
native_precision=0,
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
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(
|
AirlySensorEntityDescription(
|
||||||
key=ATTR_API_HUMIDITY,
|
key=ATTR_API_HUMIDITY,
|
||||||
device_class=SensorDeviceClass.HUMIDITY,
|
device_class=SensorDeviceClass.HUMIDITY,
|
||||||
name=ATTR_API_HUMIDITY.capitalize(),
|
name=ATTR_API_HUMIDITY.capitalize(),
|
||||||
|
native_precision=1,
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
value=lambda value: round(value, 1),
|
|
||||||
),
|
),
|
||||||
AirlySensorEntityDescription(
|
AirlySensorEntityDescription(
|
||||||
key=ATTR_API_PRESSURE,
|
key=ATTR_API_PRESSURE,
|
||||||
device_class=SensorDeviceClass.PRESSURE,
|
device_class=SensorDeviceClass.PRESSURE,
|
||||||
name=ATTR_API_PRESSURE.capitalize(),
|
name=ATTR_API_PRESSURE.capitalize(),
|
||||||
|
native_precision=0,
|
||||||
native_unit_of_measurement=UnitOfPressure.HPA,
|
native_unit_of_measurement=UnitOfPressure.HPA,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
@ -112,36 +129,56 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
|
|||||||
key=ATTR_API_TEMPERATURE,
|
key=ATTR_API_TEMPERATURE,
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
name=ATTR_API_TEMPERATURE.capitalize(),
|
name=ATTR_API_TEMPERATURE.capitalize(),
|
||||||
|
native_precision=1,
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
value=lambda value: round(value, 1),
|
|
||||||
),
|
),
|
||||||
AirlySensorEntityDescription(
|
AirlySensorEntityDescription(
|
||||||
key=ATTR_API_CO,
|
key=ATTR_API_CO,
|
||||||
name=ATTR_API_CO,
|
name=ATTR_API_CO,
|
||||||
|
native_precision=0,
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
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(
|
AirlySensorEntityDescription(
|
||||||
key=ATTR_API_NO2,
|
key=ATTR_API_NO2,
|
||||||
device_class=SensorDeviceClass.NITROGEN_DIOXIDE,
|
device_class=SensorDeviceClass.NITROGEN_DIOXIDE,
|
||||||
name=ATTR_API_NO2,
|
name=ATTR_API_NO2,
|
||||||
|
native_precision=0,
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
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(
|
AirlySensorEntityDescription(
|
||||||
key=ATTR_API_SO2,
|
key=ATTR_API_SO2,
|
||||||
device_class=SensorDeviceClass.SULPHUR_DIOXIDE,
|
device_class=SensorDeviceClass.SULPHUR_DIOXIDE,
|
||||||
name=ATTR_API_SO2,
|
name=ATTR_API_SO2,
|
||||||
|
native_precision=0,
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
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(
|
AirlySensorEntityDescription(
|
||||||
key=ATTR_API_O3,
|
key=ATTR_API_O3,
|
||||||
device_class=SensorDeviceClass.OZONE,
|
device_class=SensorDeviceClass.OZONE,
|
||||||
name=ATTR_API_O3,
|
name=ATTR_API_O3,
|
||||||
|
native_precision=0,
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
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 = (
|
self._attr_unique_id = (
|
||||||
f"{coordinator.latitude}-{coordinator.longitude}-{description.key}".lower()
|
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
|
self.entity_description = description
|
||||||
|
|
||||||
@property
|
@callback
|
||||||
def native_value(self) -> StateType:
|
def _handle_coordinator_update(self) -> None:
|
||||||
"""Return the state."""
|
"""Handle updated data from the coordinator."""
|
||||||
state = self.coordinator.data[self.entity_description.key]
|
self._attr_native_value = self.coordinator.data[self.entity_description.key]
|
||||||
return cast(StateType, self.entity_description.value(state))
|
self._attr_extra_state_attributes = self.entity_description.attrs(
|
||||||
|
self.coordinator.data
|
||||||
@property
|
)
|
||||||
def extra_state_attributes(self) -> dict[str, Any]:
|
self.async_write_ha_state()
|
||||||
"""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
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user