Add entity translations for AirNow (#94175)

* Add entity translations for AirNow

* Restore keys

* Restore keys
pull/94945/head
Joost Lekkerkerker 2023-06-20 22:24:51 +02:00 committed by GitHub
parent 18d0fe994d
commit d6dc738a12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 29 deletions

View File

@ -17,5 +17,3 @@ ATTR_API_STATION_LATITUDE = "Latitude"
ATTR_API_STATION_LONGITUDE = "Longitude"
DEFAULT_NAME = "AirNow"
DOMAIN = "airnow"
SENSOR_AQI_ATTR_DESCR = "description"
SENSOR_AQI_ATTR_LEVEL = "level"

View File

@ -1,6 +1,10 @@
"""Support for the AirNow sensor service."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any
from homeassistant.components.sensor import (
SensorEntity,
SensorEntityDescription,
@ -12,7 +16,10 @@ from homeassistant.const import (
CONCENTRATION_PARTS_PER_MILLION,
)
from homeassistant.core import HomeAssistant
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 AirNowDataUpdateCoordinator
@ -22,36 +29,61 @@ from .const import (
ATTR_API_AQI_LEVEL,
ATTR_API_O3,
ATTR_API_PM25,
DEFAULT_NAME,
DOMAIN,
SENSOR_AQI_ATTR_DESCR,
SENSOR_AQI_ATTR_LEVEL,
)
ATTRIBUTION = "Data provided by AirNow"
PARALLEL_UPDATES = 1
SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
SensorEntityDescription(
ATTR_DESCR = "description"
ATTR_LEVEL = "level"
@dataclass
class AirNowEntityDescriptionMixin:
"""Mixin for required keys."""
value_fn: Callable[[Any], StateType]
extra_state_attributes_fn: Callable[[Any], dict[str, str]] | None
@dataclass
class AirNowEntityDescription(SensorEntityDescription, AirNowEntityDescriptionMixin):
"""Describes Airnow sensor entity."""
SENSOR_TYPES: tuple[AirNowEntityDescription, ...] = (
AirNowEntityDescription(
key=ATTR_API_AQI,
translation_key="aqi",
icon="mdi:blur",
name=ATTR_API_AQI,
native_unit_of_measurement="aqi",
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda data: data.get(ATTR_API_AQI),
extra_state_attributes_fn=lambda data: {
ATTR_DESCR: data[ATTR_API_AQI_DESCRIPTION],
ATTR_LEVEL: data[ATTR_API_AQI_LEVEL],
},
),
SensorEntityDescription(
AirNowEntityDescription(
key=ATTR_API_PM25,
translation_key="pm25",
icon="mdi:blur",
name=ATTR_API_PM25,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda data: data.get(ATTR_API_PM25),
extra_state_attributes_fn=None,
),
SensorEntityDescription(
AirNowEntityDescription(
key=ATTR_API_O3,
translation_key="o3",
icon="mdi:blur",
name=ATTR_API_O3,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda data: data.get(ATTR_API_O3),
extra_state_attributes_fn=None,
),
)
@ -73,38 +105,38 @@ class AirNowSensor(CoordinatorEntity[AirNowDataUpdateCoordinator], SensorEntity)
"""Define an AirNow sensor."""
_attr_attribution = ATTRIBUTION
_attr_has_entity_name = True
entity_description: AirNowEntityDescription
def __init__(
self,
coordinator: AirNowDataUpdateCoordinator,
description: SensorEntityDescription,
description: AirNowEntityDescription,
) -> None:
"""Initialize."""
super().__init__(coordinator)
self.entity_description = description
self._state = None
self._attrs: dict[str, str] = {}
self._attr_name = f"AirNow {description.name}"
self._attr_unique_id = (
f"{coordinator.latitude}-{coordinator.longitude}-{description.key.lower()}"
)
self._attr_device_info = DeviceInfo(
entry_type=DeviceEntryType.SERVICE,
identifiers={(DOMAIN, self._attr_unique_id)},
manufacturer=DEFAULT_NAME,
name=DEFAULT_NAME,
)
@property
def native_value(self):
def native_value(self) -> StateType:
"""Return the state."""
self._state = self.coordinator.data.get(self.entity_description.key)
return self._state
return self.entity_description.value_fn(self.coordinator.data)
@property
def extra_state_attributes(self):
def extra_state_attributes(self) -> dict[str, str] | None:
"""Return the state attributes."""
if self.entity_description.key == ATTR_API_AQI:
self._attrs[SENSOR_AQI_ATTR_DESCR] = self.coordinator.data[
ATTR_API_AQI_DESCRIPTION
]
self._attrs[SENSOR_AQI_ATTR_LEVEL] = self.coordinator.data[
ATTR_API_AQI_LEVEL
]
return self._attrs
if self.entity_description.extra_state_attributes_fn:
return self.entity_description.extra_state_attributes_fn(
self.coordinator.data
)
return None

View File

@ -20,5 +20,18 @@
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
}
},
"entity": {
"sensor": {
"aqi": {
"name": "[%key:component::sensor::entity_component::aqi::name%]"
},
"pm25": {
"name": "[%key:component::sensor::entity_component::pm25::name%]"
},
"o3": {
"name": "[%key:component::sensor::entity_component::ozone::name%]"
}
}
}
}