Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for the World Air Quality Index service."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 from dataclasses import dataclass
7 import logging
8 
9 from aiowaqi import WAQIAirQuality
10 from aiowaqi.models import Pollutant
11 
13  SensorDeviceClass,
14  SensorEntity,
15  SensorEntityDescription,
16  SensorStateClass,
17 )
18 from homeassistant.config_entries import ConfigEntry
19 from homeassistant.const import PERCENTAGE, UnitOfPressure, UnitOfTemperature
20 from homeassistant.core import HomeAssistant
21 from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
22 from homeassistant.helpers.entity_platform import AddEntitiesCallback
23 from homeassistant.helpers.typing import StateType
24 from homeassistant.helpers.update_coordinator import CoordinatorEntity
25 
26 from .const import DOMAIN
27 from .coordinator import WAQIDataUpdateCoordinator
28 
29 _LOGGER = logging.getLogger(__name__)
30 
31 ATTR_DOMINENTPOL = "dominentpol"
32 ATTR_HUMIDITY = "humidity"
33 ATTR_NITROGEN_DIOXIDE = "nitrogen_dioxide"
34 ATTR_OZONE = "ozone"
35 ATTR_PM10 = "pm_10"
36 ATTR_PM2_5 = "pm_2_5"
37 ATTR_PRESSURE = "pressure"
38 ATTR_SULFUR_DIOXIDE = "sulfur_dioxide"
39 
40 
41 @dataclass(frozen=True, kw_only=True)
43  """Describes WAQI sensor entity."""
44 
45  available_fn: Callable[[WAQIAirQuality], bool] = lambda _: True
46  value_fn: Callable[[WAQIAirQuality], StateType]
47 
48 
49 SENSORS: list[WAQISensorEntityDescription] = [
51  key="air_quality",
52  device_class=SensorDeviceClass.AQI,
53  state_class=SensorStateClass.MEASUREMENT,
54  value_fn=lambda aq: aq.air_quality_index,
55  ),
57  key="humidity",
58  device_class=SensorDeviceClass.HUMIDITY,
59  native_unit_of_measurement=PERCENTAGE,
60  state_class=SensorStateClass.MEASUREMENT,
61  value_fn=lambda aq: aq.extended_air_quality.humidity,
62  available_fn=lambda aq: aq.extended_air_quality.humidity is not None,
63  ),
65  key="pressure",
66  device_class=SensorDeviceClass.PRESSURE,
67  native_unit_of_measurement=UnitOfPressure.HPA,
68  state_class=SensorStateClass.MEASUREMENT,
69  value_fn=lambda aq: aq.extended_air_quality.pressure,
70  available_fn=lambda aq: aq.extended_air_quality.pressure is not None,
71  ),
73  key="temperature",
74  device_class=SensorDeviceClass.TEMPERATURE,
75  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
76  state_class=SensorStateClass.MEASUREMENT,
77  value_fn=lambda aq: aq.extended_air_quality.temperature,
78  available_fn=lambda aq: aq.extended_air_quality.temperature is not None,
79  ),
81  key="carbon_monoxide",
82  translation_key="carbon_monoxide",
83  state_class=SensorStateClass.MEASUREMENT,
84  value_fn=lambda aq: aq.extended_air_quality.carbon_monoxide,
85  available_fn=lambda aq: aq.extended_air_quality.carbon_monoxide is not None,
86  ),
88  key="nitrogen_dioxide",
89  translation_key="nitrogen_dioxide",
90  state_class=SensorStateClass.MEASUREMENT,
91  value_fn=lambda aq: aq.extended_air_quality.nitrogen_dioxide,
92  available_fn=lambda aq: aq.extended_air_quality.nitrogen_dioxide is not None,
93  ),
95  key="ozone",
96  translation_key="ozone",
97  state_class=SensorStateClass.MEASUREMENT,
98  value_fn=lambda aq: aq.extended_air_quality.ozone,
99  available_fn=lambda aq: aq.extended_air_quality.ozone is not None,
100  ),
102  key="sulphur_dioxide",
103  translation_key="sulphur_dioxide",
104  state_class=SensorStateClass.MEASUREMENT,
105  value_fn=lambda aq: aq.extended_air_quality.sulfur_dioxide,
106  available_fn=lambda aq: aq.extended_air_quality.sulfur_dioxide is not None,
107  ),
109  key="pm10",
110  translation_key="pm10",
111  state_class=SensorStateClass.MEASUREMENT,
112  value_fn=lambda aq: aq.extended_air_quality.pm10,
113  available_fn=lambda aq: aq.extended_air_quality.pm10 is not None,
114  ),
116  key="pm25",
117  translation_key="pm25",
118  state_class=SensorStateClass.MEASUREMENT,
119  value_fn=lambda aq: aq.extended_air_quality.pm25,
120  available_fn=lambda aq: aq.extended_air_quality.pm25 is not None,
121  ),
123  key="neph",
124  translation_key="neph",
125  state_class=SensorStateClass.MEASUREMENT,
126  value_fn=lambda aq: aq.extended_air_quality.nephelometry,
127  available_fn=lambda aq: aq.extended_air_quality.nephelometry is not None,
128  entity_registry_enabled_default=False,
129  ),
131  key="dominant_pollutant",
132  translation_key="dominant_pollutant",
133  device_class=SensorDeviceClass.ENUM,
134  options=[pollutant.value for pollutant in Pollutant],
135  value_fn=lambda aq: aq.dominant_pollutant,
136  ),
137 ]
138 
139 
141  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
142 ) -> None:
143  """Set up the WAQI sensor."""
144  coordinator: WAQIDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
146  WaqiSensor(coordinator, sensor)
147  for sensor in SENSORS
148  if sensor.available_fn(coordinator.data)
149  )
150 
151 
152 class WaqiSensor(CoordinatorEntity[WAQIDataUpdateCoordinator], SensorEntity):
153  """Implementation of a WAQI sensor."""
154 
155  _attr_has_entity_name = True
156  entity_description: WAQISensorEntityDescription
157 
158  def __init__(
159  self,
160  coordinator: WAQIDataUpdateCoordinator,
161  entity_description: WAQISensorEntityDescription,
162  ) -> None:
163  """Initialize the sensor."""
164  super().__init__(coordinator)
165  self.entity_descriptionentity_description = entity_description
166  self._attr_unique_id_attr_unique_id = f"{coordinator.data.station_id}_{entity_description.key}"
167  self._attr_device_info_attr_device_info = DeviceInfo(
168  identifiers={(DOMAIN, str(coordinator.data.station_id))},
169  name=coordinator.data.city.name,
170  entry_type=DeviceEntryType.SERVICE,
171  )
172  self._attr_attribution_attr_attribution = " and ".join(
173  attribution.name for attribution in coordinator.data.attributions
174  )
175 
176  @property
177  def native_value(self) -> StateType:
178  """Return the state of the device."""
179  return self.entity_descriptionentity_description.value_fn(self.coordinator.data)
None __init__(self, WAQIDataUpdateCoordinator coordinator, WAQISensorEntityDescription entity_description)
Definition: sensor.py:162
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:142