1 """Support for AirVisual air quality sensors."""
3 from __future__
import annotations
8 SensorEntityDescription,
16 CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
17 CONCENTRATION_PARTS_PER_BILLION,
18 CONCENTRATION_PARTS_PER_MILLION,
29 from .
import AirVisualConfigEntry
30 from .const
import CONF_CITY
31 from .entity
import AirVisualEntity
34 ATTR_COUNTRY =
"country"
35 ATTR_POLLUTANT_SYMBOL =
"pollutant_symbol"
36 ATTR_POLLUTANT_UNIT =
"pollutant_unit"
37 ATTR_REGION =
"region"
39 SENSOR_KIND_AQI =
"air_quality_index"
40 SENSOR_KIND_LEVEL =
"air_pollution_level"
41 SENSOR_KIND_POLLUTANT =
"main_pollutant"
43 GEOGRAPHY_SENSOR_DESCRIPTIONS = (
45 key=SENSOR_KIND_LEVEL,
46 name=
"Air pollution level",
47 device_class=SensorDeviceClass.ENUM,
52 "unhealthy_sensitive",
56 translation_key=
"pollutant_level",
60 name=
"Air quality index",
61 device_class=SensorDeviceClass.AQI,
62 state_class=SensorStateClass.MEASUREMENT,
65 key=SENSOR_KIND_POLLUTANT,
66 name=
"Main pollutant",
67 device_class=SensorDeviceClass.ENUM,
68 options=[
"co",
"n2",
"o3",
"p1",
"p2",
"s2"],
69 translation_key=
"pollutant_label",
72 GEOGRAPHY_SENSOR_LOCALES = {
"cn":
"Chinese",
"us":
"U.S."}
75 STATE_POLLUTANT_LABEL_CO =
"co"
76 STATE_POLLUTANT_LABEL_N2 =
"n2"
77 STATE_POLLUTANT_LABEL_O3 =
"o3"
78 STATE_POLLUTANT_LABEL_P1 =
"p1"
79 STATE_POLLUTANT_LABEL_P2 =
"p2"
80 STATE_POLLUTANT_LABEL_S2 =
"s2"
82 STATE_POLLUTANT_LEVEL_GOOD =
"good"
83 STATE_POLLUTANT_LEVEL_MODERATE =
"moderate"
84 STATE_POLLUTANT_LEVEL_UNHEALTHY_SENSITIVE =
"unhealthy_sensitive"
85 STATE_POLLUTANT_LEVEL_UNHEALTHY =
"unhealthy"
86 STATE_POLLUTANT_LEVEL_VERY_UNHEALTHY =
"very_unhealthy"
87 STATE_POLLUTANT_LEVEL_HAZARDOUS =
"hazardous"
90 (0, 50): (STATE_POLLUTANT_LEVEL_GOOD,
"mdi:emoticon-excited"),
91 (51, 100): (STATE_POLLUTANT_LEVEL_MODERATE,
"mdi:emoticon-happy"),
92 (101, 150): (STATE_POLLUTANT_LEVEL_UNHEALTHY_SENSITIVE,
"mdi:emoticon-neutral"),
93 (151, 200): (STATE_POLLUTANT_LEVEL_UNHEALTHY,
"mdi:emoticon-sad"),
94 (201, 300): (STATE_POLLUTANT_LEVEL_VERY_UNHEALTHY,
"mdi:emoticon-dead"),
95 (301, 1000): (STATE_POLLUTANT_LEVEL_HAZARDOUS,
"mdi:biohazard"),
99 "co": CONCENTRATION_PARTS_PER_MILLION,
100 "n2": CONCENTRATION_PARTS_PER_BILLION,
101 "o3": CONCENTRATION_PARTS_PER_BILLION,
102 "p1": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
103 "p2": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
104 "s2": CONCENTRATION_PARTS_PER_BILLION,
110 entry: AirVisualConfigEntry,
111 async_add_entities: AddEntitiesCallback,
113 """Set up AirVisual sensors based on a config entry."""
114 coordinator = entry.runtime_data
117 for locale
in GEOGRAPHY_SENSOR_LOCALES
118 for description
in GEOGRAPHY_SENSOR_DESCRIPTIONS
123 """Define an AirVisual sensor related to geography data via the Cloud API."""
127 coordinator: DataUpdateCoordinator,
129 description: SensorEntityDescription,
133 super().
__init__(coordinator, entry, description)
137 ATTR_CITY: entry.data.get(CONF_CITY),
138 ATTR_STATE: entry.data.get(CONF_STATE),
139 ATTR_COUNTRY: entry.data.get(CONF_COUNTRY),
142 self.
_attr_name_attr_name = f
"{GEOGRAPHY_SENSOR_LOCALES[locale]} {description.name}"
148 """Return if entity is available."""
149 return super().available
and self.coordinator.data[
"current"][
"pollution"]
153 """Update the entity from the latest data."""
155 data = self.coordinator.data[
"current"][
"pollution"]
160 aqi = data[f
"aqi{self._locale}"]
163 for (floor, ceiling), (name, icon)
in POLLUTANT_LEVELS.items()
164 if floor <= aqi <= ceiling
169 symbol = data[f
"main{self._locale}"]
173 ATTR_POLLUTANT_SYMBOL: symbol,
174 ATTR_POLLUTANT_UNIT: POLLUTANT_UNITS[symbol],
185 latitude = self.
_entry_entry.data.get(
187 self.coordinator.data[
"location"][
"coordinates"][1],
189 longitude = self.
_entry_entry.data.get(
191 self.coordinator.data[
"location"][
"coordinates"][0],
194 if self.
_entry_entry.options[CONF_SHOW_ON_MAP]:
_attr_extra_state_attributes
None update_from_latest_data(self)
None __init__(self, DataUpdateCoordinator coordinator, ConfigEntry entry, SensorEntityDescription description, str locale)
None async_setup_entry(HomeAssistant hass, AirVisualConfigEntry entry, AddEntitiesCallback async_add_entities)
IssData update(pyiss.ISS iss)