mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Parse AirNow observation timezone correctly (#122006)
Parse observation timezone correctly Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
bd3efe57f7
commit
705af35dd6
@ -14,10 +14,32 @@ ATTR_API_POLLUTANT = "Pollutant"
|
||||
ATTR_API_REPORT_DATE = "DateObserved"
|
||||
ATTR_API_REPORT_HOUR = "HourObserved"
|
||||
ATTR_API_REPORT_TZ = "LocalTimeZone"
|
||||
ATTR_API_REPORT_TZINFO = "LocalTimeZoneInfo"
|
||||
ATTR_API_STATE = "StateCode"
|
||||
ATTR_API_STATION = "ReportingArea"
|
||||
ATTR_API_STATION_LATITUDE = "Latitude"
|
||||
ATTR_API_STATION_LONGITUDE = "Longitude"
|
||||
DEFAULT_NAME = "AirNow"
|
||||
DOMAIN = "airnow"
|
||||
|
||||
SECONDS_PER_HOUR = 3600
|
||||
|
||||
# AirNow seems to only use standard time zones,
|
||||
# but we include daylight savings for completeness/futureproofing.
|
||||
US_TZ_OFFSETS = {
|
||||
"HST": -10 * SECONDS_PER_HOUR,
|
||||
"HDT": -9 * SECONDS_PER_HOUR,
|
||||
# AirNow returns AKT instead of AKST or AKDT, use standard
|
||||
"AKT": -9 * SECONDS_PER_HOUR,
|
||||
"AKST": -9 * SECONDS_PER_HOUR,
|
||||
"AKDT": -8 * SECONDS_PER_HOUR,
|
||||
"PST": -8 * SECONDS_PER_HOUR,
|
||||
"PDT": -7 * SECONDS_PER_HOUR,
|
||||
"MST": -7 * SECONDS_PER_HOUR,
|
||||
"MDT": -6 * SECONDS_PER_HOUR,
|
||||
"CST": -6 * SECONDS_PER_HOUR,
|
||||
"CDT": -5 * SECONDS_PER_HOUR,
|
||||
"EST": -5 * SECONDS_PER_HOUR,
|
||||
"EDT": -4 * SECONDS_PER_HOUR,
|
||||
"AST": -4 * SECONDS_PER_HOUR,
|
||||
"ADT": -3 * SECONDS_PER_HOUR,
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ from pyairnow.errors import AirNowError
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .const import (
|
||||
ATTR_API_AQI,
|
||||
@ -27,7 +26,6 @@ from .const import (
|
||||
ATTR_API_REPORT_DATE,
|
||||
ATTR_API_REPORT_HOUR,
|
||||
ATTR_API_REPORT_TZ,
|
||||
ATTR_API_REPORT_TZINFO,
|
||||
ATTR_API_STATE,
|
||||
ATTR_API_STATION,
|
||||
ATTR_API_STATION_LATITUDE,
|
||||
@ -98,9 +96,7 @@ class AirNowDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
# Copy Report Details
|
||||
data[ATTR_API_REPORT_DATE] = obv[ATTR_API_REPORT_DATE]
|
||||
data[ATTR_API_REPORT_HOUR] = obv[ATTR_API_REPORT_HOUR]
|
||||
data[ATTR_API_REPORT_TZINFO] = await dt_util.async_get_time_zone(
|
||||
obv[ATTR_API_REPORT_TZ]
|
||||
)
|
||||
data[ATTR_API_REPORT_TZ] = obv[ATTR_API_REPORT_TZ]
|
||||
|
||||
# Copy Station Details
|
||||
data[ATTR_API_STATE] = obv[ATTR_API_STATE]
|
||||
|
@ -4,9 +4,10 @@ from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from dateutil import parser
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
SensorEntity,
|
||||
@ -34,12 +35,13 @@ from .const import (
|
||||
ATTR_API_PM25,
|
||||
ATTR_API_REPORT_DATE,
|
||||
ATTR_API_REPORT_HOUR,
|
||||
ATTR_API_REPORT_TZINFO,
|
||||
ATTR_API_REPORT_TZ,
|
||||
ATTR_API_STATION,
|
||||
ATTR_API_STATION_LATITUDE,
|
||||
ATTR_API_STATION_LONGITUDE,
|
||||
DEFAULT_NAME,
|
||||
DOMAIN,
|
||||
US_TZ_OFFSETS,
|
||||
)
|
||||
|
||||
ATTRIBUTION = "Data provided by AirNow"
|
||||
@ -69,6 +71,18 @@ def station_extra_attrs(data: dict[str, Any]) -> dict[str, Any]:
|
||||
return {}
|
||||
|
||||
|
||||
def aqi_extra_attrs(data: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Process extra attributes for main AQI sensor."""
|
||||
return {
|
||||
ATTR_DESCR: data[ATTR_API_AQI_DESCRIPTION],
|
||||
ATTR_LEVEL: data[ATTR_API_AQI_LEVEL],
|
||||
ATTR_TIME: parser.parse(
|
||||
f"{data[ATTR_API_REPORT_DATE]} {data[ATTR_API_REPORT_HOUR]}:00 {data[ATTR_API_REPORT_TZ]}",
|
||||
tzinfos=US_TZ_OFFSETS,
|
||||
).isoformat(),
|
||||
}
|
||||
|
||||
|
||||
SENSOR_TYPES: tuple[AirNowEntityDescription, ...] = (
|
||||
AirNowEntityDescription(
|
||||
key=ATTR_API_AQI,
|
||||
@ -76,16 +90,7 @@ SENSOR_TYPES: tuple[AirNowEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
device_class=SensorDeviceClass.AQI,
|
||||
value_fn=lambda data: data.get(ATTR_API_AQI),
|
||||
extra_state_attributes_fn=lambda data: {
|
||||
ATTR_DESCR: data[ATTR_API_AQI_DESCRIPTION],
|
||||
ATTR_LEVEL: data[ATTR_API_AQI_LEVEL],
|
||||
ATTR_TIME: datetime.strptime(
|
||||
f"{data[ATTR_API_REPORT_DATE]} {data[ATTR_API_REPORT_HOUR]}",
|
||||
"%Y-%m-%d %H",
|
||||
)
|
||||
.replace(tzinfo=data[ATTR_API_REPORT_TZINFO])
|
||||
.isoformat(),
|
||||
},
|
||||
extra_state_attributes_fn=aqi_extra_attrs,
|
||||
),
|
||||
AirNowEntityDescription(
|
||||
key=ATTR_API_PM10,
|
||||
|
@ -8,7 +8,7 @@
|
||||
'DateObserved': '2020-12-20',
|
||||
'HourObserved': 15,
|
||||
'Latitude': '**REDACTED**',
|
||||
'LocalTimeZoneInfo': 'PST',
|
||||
'LocalTimeZone': 'PST',
|
||||
'Longitude': '**REDACTED**',
|
||||
'O3': 0.048,
|
||||
'PM10': 12,
|
||||
|
Loading…
x
Reference in New Issue
Block a user