Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """DataUpdateCoordinator for the AirNow integration."""
2 
3 from datetime import timedelta
4 import logging
5 from typing import Any
6 
7 from aiohttp import ClientSession
8 from aiohttp.client_exceptions import ClientConnectorError
9 from pyairnow import WebServiceAPI
10 from pyairnow.conv import aqi_to_concentration
11 from pyairnow.errors import AirNowError
12 
13 from homeassistant.core import HomeAssistant
14 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
15 
16 from .const import (
17  ATTR_API_AQI,
18  ATTR_API_AQI_DESCRIPTION,
19  ATTR_API_AQI_LEVEL,
20  ATTR_API_AQI_PARAM,
21  ATTR_API_CAT_DESCRIPTION,
22  ATTR_API_CAT_LEVEL,
23  ATTR_API_CATEGORY,
24  ATTR_API_PM25,
25  ATTR_API_POLLUTANT,
26  ATTR_API_REPORT_DATE,
27  ATTR_API_REPORT_HOUR,
28  ATTR_API_REPORT_TZ,
29  ATTR_API_STATE,
30  ATTR_API_STATION,
31  ATTR_API_STATION_LATITUDE,
32  ATTR_API_STATION_LONGITUDE,
33  DOMAIN,
34 )
35 
36 _LOGGER = logging.getLogger(__name__)
37 
38 
40  """The AirNow update coordinator."""
41 
42  def __init__(
43  self,
44  hass: HomeAssistant,
45  session: ClientSession,
46  api_key: str,
47  latitude: float,
48  longitude: float,
49  distance: int,
50  update_interval: timedelta,
51  ) -> None:
52  """Initialize."""
53  self.latitudelatitude = latitude
54  self.longitudelongitude = longitude
55  self.distancedistance = distance
56 
57  self.airnowairnow = WebServiceAPI(api_key, session=session)
58 
59  super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
60 
61  async def _async_update_data(self) -> dict[str, Any]:
62  """Update data via library."""
63  data = {}
64  try:
65  obs = await self.airnowairnow.observations.latLong(
66  self.latitudelatitude,
67  self.longitudelongitude,
68  distance=self.distancedistance,
69  )
70 
71  except (AirNowError, ClientConnectorError) as error:
72  raise UpdateFailed(error) from error
73 
74  if not obs:
75  raise UpdateFailed("No data was returned from AirNow")
76 
77  max_aqi = 0
78  max_aqi_level = 0
79  max_aqi_desc = ""
80  max_aqi_poll = ""
81  for obv in obs:
82  # Convert AQIs to Concentration
83  pollutant = obv[ATTR_API_AQI_PARAM]
84  concentration = aqi_to_concentration(obv[ATTR_API_AQI], pollutant)
85  data[obv[ATTR_API_AQI_PARAM]] = concentration
86 
87  # Overall AQI is the max of all pollutant AQIs
88  if obv[ATTR_API_AQI] > max_aqi:
89  max_aqi = obv[ATTR_API_AQI]
90  max_aqi_level = obv[ATTR_API_CATEGORY][ATTR_API_CAT_LEVEL]
91  max_aqi_desc = obv[ATTR_API_CATEGORY][ATTR_API_CAT_DESCRIPTION]
92  max_aqi_poll = pollutant
93 
94  # Copy other data from PM2.5 Value
95  if obv[ATTR_API_AQI_PARAM] == ATTR_API_PM25:
96  # Copy Report Details
97  data[ATTR_API_REPORT_DATE] = obv[ATTR_API_REPORT_DATE]
98  data[ATTR_API_REPORT_HOUR] = obv[ATTR_API_REPORT_HOUR]
99  data[ATTR_API_REPORT_TZ] = obv[ATTR_API_REPORT_TZ]
100 
101  # Copy Station Details
102  data[ATTR_API_STATE] = obv[ATTR_API_STATE]
103  data[ATTR_API_STATION] = obv[ATTR_API_STATION]
104  data[ATTR_API_STATION_LATITUDE] = obv[ATTR_API_STATION_LATITUDE]
105  data[ATTR_API_STATION_LONGITUDE] = obv[ATTR_API_STATION_LONGITUDE]
106 
107  # Store Overall AQI
108  data[ATTR_API_AQI] = max_aqi
109  data[ATTR_API_AQI_LEVEL] = max_aqi_level
110  data[ATTR_API_AQI_DESCRIPTION] = max_aqi_desc
111  data[ATTR_API_POLLUTANT] = max_aqi_poll
112 
113  return data
None __init__(self, HomeAssistant hass, ClientSession session, str api_key, float latitude, float longitude, int distance, timedelta update_interval)
Definition: coordinator.py:51