Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """The AccuWeather coordinator."""
2 
3 from __future__ import annotations
4 
5 from asyncio import timeout
6 from dataclasses import dataclass
7 from datetime import timedelta
8 import logging
9 from typing import TYPE_CHECKING, Any
10 
11 from accuweather import AccuWeather, ApiError, InvalidApiKeyError, RequestsExceededError
12 from aiohttp.client_exceptions import ClientConnectorError
13 
14 from homeassistant.config_entries import ConfigEntry
15 from homeassistant.core import HomeAssistant
16 from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
18  DataUpdateCoordinator,
19  TimestampDataUpdateCoordinator,
20  UpdateFailed,
21 )
22 
23 from .const import DOMAIN, MANUFACTURER
24 
25 EXCEPTIONS = (ApiError, ClientConnectorError, InvalidApiKeyError, RequestsExceededError)
26 
27 _LOGGER = logging.getLogger(__name__)
28 
29 
30 @dataclass
32  """Data for AccuWeather integration."""
33 
34  coordinator_observation: AccuWeatherObservationDataUpdateCoordinator
35  coordinator_daily_forecast: AccuWeatherDailyForecastDataUpdateCoordinator
36 
37 
38 type AccuWeatherConfigEntry = ConfigEntry[AccuWeatherData]
39 
40 
42  DataUpdateCoordinator[dict[str, Any]]
43 ):
44  """Class to manage fetching AccuWeather data API."""
45 
46  def __init__(
47  self,
48  hass: HomeAssistant,
49  config_entry: AccuWeatherConfigEntry,
50  accuweather: AccuWeather,
51  name: str,
52  coordinator_type: str,
53  update_interval: timedelta,
54  ) -> None:
55  """Initialize."""
56  self.accuweatheraccuweather = accuweather
57  self.location_keylocation_key = accuweather.location_key
58 
59  if TYPE_CHECKING:
60  assert self.location_keylocation_key is not None
61 
62  self.device_infodevice_info = _get_device_info(self.location_keylocation_key, name)
63 
64  super().__init__(
65  hass,
66  _LOGGER,
67  config_entry=config_entry,
68  name=f"{name} ({coordinator_type})",
69  update_interval=update_interval,
70  )
71 
72  async def _async_update_data(self) -> dict[str, Any]:
73  """Update data via library."""
74  try:
75  async with timeout(10):
76  result = await self.accuweatheraccuweather.async_get_current_conditions()
77  except EXCEPTIONS as error:
78  raise UpdateFailed(error) from error
79 
80  _LOGGER.debug("Requests remaining: %d", self.accuweatheraccuweather.requests_remaining)
81 
82  return result
83 
84 
86  TimestampDataUpdateCoordinator[list[dict[str, Any]]]
87 ):
88  """Class to manage fetching AccuWeather data API."""
89 
90  def __init__(
91  self,
92  hass: HomeAssistant,
93  config_entry: AccuWeatherConfigEntry,
94  accuweather: AccuWeather,
95  name: str,
96  coordinator_type: str,
97  update_interval: timedelta,
98  ) -> None:
99  """Initialize."""
100  self.accuweatheraccuweather = accuweather
101  self.location_keylocation_key = accuweather.location_key
102 
103  if TYPE_CHECKING:
104  assert self.location_keylocation_key is not None
105 
106  self.device_infodevice_info = _get_device_info(self.location_keylocation_key, name)
107 
108  super().__init__(
109  hass,
110  _LOGGER,
111  config_entry=config_entry,
112  name=f"{name} ({coordinator_type})",
113  update_interval=update_interval,
114  )
115 
116  async def _async_update_data(self) -> list[dict[str, Any]]:
117  """Update data via library."""
118  try:
119  async with timeout(10):
120  result = await self.accuweatheraccuweather.async_get_daily_forecast()
121  except EXCEPTIONS as error:
122  raise UpdateFailed(error) from error
123 
124  _LOGGER.debug("Requests remaining: %d", self.accuweatheraccuweather.requests_remaining)
125 
126  return result
127 
128 
129 def _get_device_info(location_key: str, name: str) -> DeviceInfo:
130  """Get device info."""
131  return DeviceInfo(
132  entry_type=DeviceEntryType.SERVICE,
133  identifiers={(DOMAIN, location_key)},
134  manufacturer=MANUFACTURER,
135  name=name,
136  # You don't need to provide specific details for the URL,
137  # so passing in _ characters is fine if the location key
138  # is correct
139  configuration_url=(
140  "http://accuweather.com/en/"
141  f"_/_/{location_key}/weather-forecast/{location_key}/"
142  ),
143  )
None __init__(self, HomeAssistant hass, AccuWeatherConfigEntry config_entry, AccuWeather accuweather, str name, str coordinator_type, timedelta update_interval)
Definition: coordinator.py:98
None __init__(self, HomeAssistant hass, AccuWeatherConfigEntry config_entry, AccuWeather accuweather, str name, str coordinator_type, timedelta update_interval)
Definition: coordinator.py:54
DeviceInfo _get_device_info(str location_key, str name)
Definition: coordinator.py:129