Simplify AirVisual Pro sensor implementation (#84898)
* Simplify AirVisual Pro sensor implementation * Code review
This commit is contained in:
parent
34b5928707
commit
e62ee331c7
2 changed files with 54 additions and 80 deletions
|
@ -1,6 +1,8 @@
|
|||
"""Support for AirVisual Pro sensors."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
|
@ -23,78 +25,93 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||
from . import AirVisualProData, AirVisualProEntity
|
||||
from .const import DOMAIN
|
||||
|
||||
SENSOR_KIND_AQI = "air_quality_index"
|
||||
SENSOR_KIND_BATTERY_LEVEL = "battery_level"
|
||||
SENSOR_KIND_CO2 = "carbon_dioxide"
|
||||
SENSOR_KIND_HUMIDITY = "humidity"
|
||||
SENSOR_KIND_PM_0_1 = "particulate_matter_0_1"
|
||||
SENSOR_KIND_PM_1_0 = "particulate_matter_1_0"
|
||||
SENSOR_KIND_PM_2_5 = "particulate_matter_2_5"
|
||||
SENSOR_KIND_SENSOR_LIFE = "sensor_life"
|
||||
SENSOR_KIND_TEMPERATURE = "temperature"
|
||||
SENSOR_KIND_VOC = "voc"
|
||||
|
||||
@dataclass
|
||||
class AirVisualProMeasurementKeyMixin:
|
||||
"""Define an entity description mixin to include a measurement key."""
|
||||
|
||||
value_fn: Callable[[dict[str, Any], dict[str, Any], dict[str, Any]], float | int]
|
||||
|
||||
|
||||
@dataclass
|
||||
class AirVisualProMeasurementDescription(
|
||||
SensorEntityDescription, AirVisualProMeasurementKeyMixin
|
||||
):
|
||||
"""Describe an AirVisual Pro sensor."""
|
||||
|
||||
|
||||
SENSOR_DESCRIPTIONS = (
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_AQI,
|
||||
AirVisualProMeasurementDescription(
|
||||
key="air_quality_index",
|
||||
name="Air quality index",
|
||||
device_class=SensorDeviceClass.AQI,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda settings, status, measurements: measurements[
|
||||
async_get_aqi_locale(settings)
|
||||
],
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_BATTERY_LEVEL,
|
||||
AirVisualProMeasurementDescription(
|
||||
key="battery_level",
|
||||
name="Battery",
|
||||
device_class=SensorDeviceClass.BATTERY,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
value_fn=lambda settings, status, measurements: status["battery"],
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_CO2,
|
||||
AirVisualProMeasurementDescription(
|
||||
key="carbon_dioxide",
|
||||
name="C02",
|
||||
device_class=SensorDeviceClass.CO2,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda settings, status, measurements: measurements["co2"],
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_HUMIDITY,
|
||||
AirVisualProMeasurementDescription(
|
||||
key="humidity",
|
||||
name="Humidity",
|
||||
device_class=SensorDeviceClass.HUMIDITY,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
value_fn=lambda settings, status, measurements: measurements["humidity"],
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_PM_0_1,
|
||||
AirVisualProMeasurementDescription(
|
||||
key="particulate_matter_0_1",
|
||||
name="PM 0.1",
|
||||
device_class=SensorDeviceClass.PM1,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda settings, status, measurements: measurements["pm0_1"],
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_PM_1_0,
|
||||
AirVisualProMeasurementDescription(
|
||||
key="particulate_matter_1_0",
|
||||
name="PM 1.0",
|
||||
device_class=SensorDeviceClass.PM10,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda settings, status, measurements: measurements["pm1_0"],
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_PM_2_5,
|
||||
AirVisualProMeasurementDescription(
|
||||
key="particulate_matter_2_5",
|
||||
name="PM 2.5",
|
||||
device_class=SensorDeviceClass.PM25,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda settings, status, measurements: measurements["pm2_5"],
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_TEMPERATURE,
|
||||
AirVisualProMeasurementDescription(
|
||||
key="temperature",
|
||||
name="Temperature",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda settings, status, measurements: measurements["temperature_C"],
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_VOC,
|
||||
AirVisualProMeasurementDescription(
|
||||
key="voc",
|
||||
name="VOC",
|
||||
device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda settings, status, measurements: measurements["voc"],
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -124,40 +141,13 @@ class AirVisualProSensor(AirVisualProEntity, SensorEntity):
|
|||
|
||||
_attr_has_entity_name = True
|
||||
|
||||
MEASUREMENTS_KEY_TO_VALUE = {
|
||||
SENSOR_KIND_CO2: "co2",
|
||||
SENSOR_KIND_HUMIDITY: "humidity",
|
||||
SENSOR_KIND_PM_0_1: "pm0_1",
|
||||
SENSOR_KIND_PM_1_0: "pm1_0",
|
||||
SENSOR_KIND_PM_2_5: "pm2_5",
|
||||
SENSOR_KIND_TEMPERATURE: "temperature_C",
|
||||
SENSOR_KIND_VOC: "voc",
|
||||
}
|
||||
entity_description: AirVisualProMeasurementDescription
|
||||
|
||||
@property
|
||||
def measurements(self) -> dict[str, Any]:
|
||||
"""Define measurements data."""
|
||||
return self.coordinator.data["measurements"]
|
||||
|
||||
@property
|
||||
def settings(self) -> dict[str, Any]:
|
||||
"""Define settings data."""
|
||||
return self.coordinator.data["settings"]
|
||||
|
||||
@property
|
||||
def status(self) -> dict[str, Any]:
|
||||
"""Define status data."""
|
||||
return self.coordinator.data["status"]
|
||||
|
||||
@callback
|
||||
def _async_update_from_latest_data(self) -> None:
|
||||
"""Update the entity from the latest data."""
|
||||
if self.entity_description.key == SENSOR_KIND_AQI:
|
||||
locale = async_get_aqi_locale(self.settings)
|
||||
self._attr_native_value = self.measurements[locale]
|
||||
elif self.entity_description.key == SENSOR_KIND_BATTERY_LEVEL:
|
||||
self._attr_native_value = self.status["battery"]
|
||||
else:
|
||||
self._attr_native_value = self.measurements[
|
||||
self.MEASUREMENTS_KEY_TO_VALUE[self.entity_description.key]
|
||||
]
|
||||
def native_value(self) -> float | int:
|
||||
"""Return the sensor value."""
|
||||
return self.entity_description.value_fn(
|
||||
self.coordinator.data["settings"],
|
||||
self.coordinator.data["status"],
|
||||
self.coordinator.data["measurements"],
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue