Migrate WAQI to aiowaqi library (#98000)

* Migrate WAQI to aiowaqi library

* Migrate WAQI to aiowaqi library

* Migrate WAQI to aiowaqi library
This commit is contained in:
Joost Lekkerkerker 2023-08-10 20:18:57 +02:00 committed by GitHub
parent 4e8b81370e
commit 82ade574d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 58 deletions

View File

@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/waqi", "documentation": "https://www.home-assistant.io/integrations/waqi",
"iot_class": "cloud_polling", "iot_class": "cloud_polling",
"loggers": ["waqiasync"], "loggers": ["waqiasync"],
"requirements": ["waqiasync==1.1.0"] "requirements": ["aiowaqi==0.2.1"]
} }

View File

@ -1,14 +1,11 @@
"""Support for the World Air Quality Index service.""" """Support for the World Air Quality Index service."""
from __future__ import annotations from __future__ import annotations
import asyncio
from contextlib import suppress
from datetime import timedelta from datetime import timedelta
import logging import logging
import aiohttp from aiowaqi import WAQIAirQuality, WAQIClient, WAQIConnectionError, WAQISearchResult
import voluptuous as vol import voluptuous as vol
from waqiasync import WaqiClient
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorDeviceClass, SensorDeviceClass,
@ -39,17 +36,6 @@ ATTR_PM2_5 = "pm_2_5"
ATTR_PRESSURE = "pressure" ATTR_PRESSURE = "pressure"
ATTR_SULFUR_DIOXIDE = "sulfur_dioxide" ATTR_SULFUR_DIOXIDE = "sulfur_dioxide"
KEY_TO_ATTR = {
"pm25": ATTR_PM2_5,
"pm10": ATTR_PM10,
"h": ATTR_HUMIDITY,
"p": ATTR_PRESSURE,
"t": ATTR_TEMPERATURE,
"o3": ATTR_OZONE,
"no2": ATTR_NITROGEN_DIOXIDE,
"so2": ATTR_SULFUR_DIOXIDE,
}
ATTRIBUTION = "Data provided by the World Air Quality Index project" ATTRIBUTION = "Data provided by the World Air Quality Index project"
ATTR_ICON = "mdi:cloud" ATTR_ICON = "mdi:cloud"
@ -82,7 +68,8 @@ async def async_setup_platform(
station_filter = config.get(CONF_STATIONS) station_filter = config.get(CONF_STATIONS)
locations = config[CONF_LOCATIONS] locations = config[CONF_LOCATIONS]
client = WaqiClient(token, async_get_clientsession(hass), timeout=TIMEOUT) client = WAQIClient(session=async_get_clientsession(hass), request_timeout=TIMEOUT)
client.authenticate(token)
dev = [] dev = []
try: try:
for location_name in locations: for location_name in locations:
@ -96,10 +83,7 @@ async def async_setup_platform(
waqi_sensor.station_name, waqi_sensor.station_name,
} & set(station_filter): } & set(station_filter):
dev.append(waqi_sensor) dev.append(waqi_sensor)
except ( except WAQIConnectionError as err:
aiohttp.client_exceptions.ClientConnectorError,
asyncio.TimeoutError,
) as err:
_LOGGER.exception("Failed to connect to WAQI servers") _LOGGER.exception("Failed to connect to WAQI servers")
raise PlatformNotReady from err raise PlatformNotReady from err
async_add_entities(dev, True) async_add_entities(dev, True)
@ -112,25 +96,14 @@ class WaqiSensor(SensorEntity):
_attr_device_class = SensorDeviceClass.AQI _attr_device_class = SensorDeviceClass.AQI
_attr_state_class = SensorStateClass.MEASUREMENT _attr_state_class = SensorStateClass.MEASUREMENT
def __init__(self, client, station): _data: WAQIAirQuality | None = None
def __init__(self, client: WAQIClient, search_result: WAQISearchResult) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
self._client = client self._client = client
try: self.uid = search_result.station_id
self.uid = station["uid"] self.url = search_result.station.external_url
except (KeyError, TypeError): self.station_name = search_result.station.name
self.uid = None
try:
self.url = station["station"]["url"]
except (KeyError, TypeError):
self.url = None
try:
self.station_name = station["station"]["name"]
except (KeyError, TypeError):
self.station_name = None
self._data = None
@property @property
def name(self): def name(self):
@ -140,12 +113,10 @@ class WaqiSensor(SensorEntity):
return f"WAQI {self.url if self.url else self.uid}" return f"WAQI {self.url if self.url else self.uid}"
@property @property
def native_value(self): def native_value(self) -> int | None:
"""Return the state of the device.""" """Return the state of the device."""
if (value := self._data.get("aqi")) is not None: assert self._data
with suppress(ValueError): return self._data.air_quality_index
return float(value)
return None
@property @property
def available(self): def available(self):
@ -166,28 +137,35 @@ class WaqiSensor(SensorEntity):
try: try:
attrs[ATTR_ATTRIBUTION] = " and ".join( attrs[ATTR_ATTRIBUTION] = " and ".join(
[ATTRIBUTION] [ATTRIBUTION]
+ [v["name"] for v in self._data.get("attributions", [])] + [attribution.name for attribution in self._data.attributions]
) )
attrs[ATTR_TIME] = self._data["time"]["s"] attrs[ATTR_TIME] = self._data.measured_at
attrs[ATTR_DOMINENTPOL] = self._data.get("dominentpol") attrs[ATTR_DOMINENTPOL] = self._data.dominant_pollutant
iaqi = self._data["iaqi"] iaqi = self._data.extended_air_quality
for key in iaqi:
if key in KEY_TO_ATTR: attribute = {
attrs[KEY_TO_ATTR[key]] = iaqi[key]["v"] ATTR_PM2_5: iaqi.pm25,
else: ATTR_PM10: iaqi.pm10,
attrs[key] = iaqi[key]["v"] ATTR_HUMIDITY: iaqi.humidity,
return attrs ATTR_PRESSURE: iaqi.pressure,
ATTR_TEMPERATURE: iaqi.temperature,
ATTR_OZONE: iaqi.ozone,
ATTR_NITROGEN_DIOXIDE: iaqi.nitrogen_dioxide,
ATTR_SULFUR_DIOXIDE: iaqi.sulfur_dioxide,
}
res_attributes = {k: v for k, v in attribute.items() if v is not None}
return {**attrs, **res_attributes}
except (IndexError, KeyError): except (IndexError, KeyError):
return {ATTR_ATTRIBUTION: ATTRIBUTION} return {ATTR_ATTRIBUTION: ATTRIBUTION}
async def async_update(self) -> None: async def async_update(self) -> None:
"""Get the latest data and updates the states.""" """Get the latest data and updates the states."""
if self.uid: if self.uid:
result = await self._client.get_station_by_number(self.uid) result = await self._client.get_by_station_number(self.uid)
elif self.url: elif self.url:
result = await self._client.get_station_by_name(self.url) result = await self._client.get_by_name(self.url)
else: else:
result = None result = None
self._data = result self._data = result

View File

@ -365,6 +365,9 @@ aiounifi==51
# homeassistant.components.vlc_telnet # homeassistant.components.vlc_telnet
aiovlc==0.1.0 aiovlc==0.1.0
# homeassistant.components.waqi
aiowaqi==0.2.1
# homeassistant.components.watttime # homeassistant.components.watttime
aiowatttime==0.1.1 aiowatttime==0.1.1
@ -2655,9 +2658,6 @@ wakeonlan==2.1.0
# homeassistant.components.wallbox # homeassistant.components.wallbox
wallbox==0.4.12 wallbox==0.4.12
# homeassistant.components.waqi
waqiasync==1.1.0
# homeassistant.components.folder_watcher # homeassistant.components.folder_watcher
watchdog==2.3.1 watchdog==2.3.1