Home Assistant Unofficial Reference 2024.12.1
api_data.py
Go to the documentation of this file.
1 """Data for all Kaiterra devices."""
2 
3 import asyncio
4 from logging import getLogger
5 
6 from aiohttp.client_exceptions import ClientConnectorError, ClientResponseError
7 from kaiterra_async_client import AQIStandard, KaiterraAPIClient, Units
8 
9 from homeassistant.const import CONF_API_KEY, CONF_DEVICE_ID, CONF_DEVICES, CONF_TYPE
10 from homeassistant.helpers.dispatcher import async_dispatcher_send
11 
12 from .const import (
13  AQI_LEVEL,
14  AQI_SCALE,
15  CONF_AQI_STANDARD,
16  CONF_PREFERRED_UNITS,
17  DISPATCHER_KAITERRA,
18 )
19 
20 _LOGGER = getLogger(__name__)
21 
22 POLLUTANTS = {"rpm25c": "PM2.5", "rpm10c": "PM10", "rtvoc": "TVOC", "rco2": "CO2"}
23 
24 
26  """Get data from Kaiterra API."""
27 
28  def __init__(self, hass, config, session):
29  """Initialize the API data object."""
30 
31  api_key = config[CONF_API_KEY]
32  aqi_standard = config[CONF_AQI_STANDARD]
33  devices = config[CONF_DEVICES]
34  units = config[CONF_PREFERRED_UNITS]
35 
36  self._hass_hass = hass
37  self._api_api = KaiterraAPIClient(
38  session,
39  api_key=api_key,
40  aqi_standard=AQIStandard.from_str(aqi_standard),
41  preferred_units=[Units.from_str(unit) for unit in units],
42  )
43  self._devices_ids_devices_ids = [device[CONF_DEVICE_ID] for device in devices]
44  self._devices_devices = [
45  f"/{device[CONF_TYPE]}s/{device[CONF_DEVICE_ID]}" for device in devices
46  ]
47  self._scale_scale = AQI_SCALE[aqi_standard]
48  self._level_level = AQI_LEVEL[aqi_standard]
49  self._update_listeners_update_listeners = []
50  self.datadata = {}
51 
52  async def async_update(self) -> None:
53  """Get the data from Kaiterra API."""
54 
55  try:
56  async with asyncio.timeout(10):
57  data = await self._api_api.get_latest_sensor_readings(self._devices_devices)
58  except (ClientResponseError, ClientConnectorError, TimeoutError) as err:
59  _LOGGER.debug("Couldn't fetch data from Kaiterra API: %s", err)
60  self.datadata = {}
61  async_dispatcher_send(self._hass_hass, DISPATCHER_KAITERRA)
62  return
63 
64  _LOGGER.debug("New data retrieved: %s", data)
65 
66  try:
67  self.datadata = {}
68  for i, device in enumerate(data):
69  if not device:
70  self.datadata[self._devices_ids_devices_ids[i]] = {}
71  continue
72 
73  aqi, main_pollutant = None, None
74  for sensor_name, sensor in device.items():
75  if not (points := sensor.get("points")):
76  continue
77 
78  point = points[0]
79  sensor["value"] = point.get("value")
80 
81  if "aqi" not in point:
82  continue
83 
84  sensor["aqi"] = point["aqi"]
85  if not aqi or aqi < point["aqi"]:
86  aqi = point["aqi"]
87  main_pollutant = POLLUTANTS.get(sensor_name)
88 
89  level = None
90  if aqi is not None:
91  for j in range(1, len(self._scale_scale)):
92  if aqi <= self._scale_scale[j]:
93  level = self._level_level[j - 1]
94  break
95 
96  device["aqi"] = {"value": aqi}
97  device["aqi_level"] = {"value": level}
98  device["aqi_pollutant"] = {"value": main_pollutant}
99 
100  self.datadata[self._devices_ids_devices_ids[i]] = device
101  except IndexError as err:
102  _LOGGER.error("Parsing error %s", err)
103  except TypeError as err:
104  _LOGGER.error("Type error %s", err)
105 
106  async_dispatcher_send(self._hass_hass, DISPATCHER_KAITERRA)
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)
Definition: dispatcher.py:193