Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """DataUpdateCoordinator for the nina integration."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 from dataclasses import dataclass
7 import re
8 from typing import Any
9 
10 from pynina import ApiError, Nina
11 
12 from homeassistant.core import HomeAssistant
13 from homeassistant.helpers.aiohttp_client import async_get_clientsession
14 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
15 
16 from .const import _LOGGER, DOMAIN, SCAN_INTERVAL
17 
18 
19 @dataclass
21  """Class to hold the warning data."""
22 
23  id: str
24  headline: str
25  description: str
26  sender: str
27  severity: str
28  recommended_actions: str
29  affected_areas: str
30  web: str
31  sent: str
32  start: str
33  expires: str
34  is_valid: bool
35 
36 
38  DataUpdateCoordinator[dict[str, list[NinaWarningData]]]
39 ):
40  """Class to manage fetching NINA data API."""
41 
42  def __init__(
43  self,
44  hass: HomeAssistant,
45  regions: dict[str, str],
46  headline_filter: str,
47  area_filter: str,
48  ) -> None:
49  """Initialize."""
50  self._regions: dict[str, str] = regions
51  self._nina: Nina = Nina(async_get_clientsession(hass))
52  self.headline_filter: str = headline_filter
53  self.area_filter: str = area_filter
54 
55  for region in regions:
56  self._nina.addRegion(region)
57 
58  super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL)
59 
60  async def _async_update_data(self) -> dict[str, list[NinaWarningData]]:
61  """Update data."""
62  async with asyncio.timeout(10):
63  try:
64  await self._nina.update()
65  except ApiError as err:
66  raise UpdateFailed(err) from err
67  return self._parse_data_parse_data()
68 
69  @staticmethod
71  warnings: dict[str, list[Any]],
72  ) -> dict[str, list[Any]]:
73  """Remove warnings with the same title and expires timestamp in a region."""
74  all_filtered_warnings: dict[str, list[Any]] = {}
75 
76  for region_id, raw_warnings in warnings.items():
77  filtered_warnings: list[Any] = []
78  processed_details: list[tuple[str, str]] = []
79 
80  for raw_warn in raw_warnings:
81  if (raw_warn.headline, raw_warn.expires) in processed_details:
82  continue
83 
84  processed_details.append((raw_warn.headline, raw_warn.expires))
85 
86  filtered_warnings.append(raw_warn)
87 
88  all_filtered_warnings[region_id] = filtered_warnings
89 
90  return all_filtered_warnings
91 
92  def _parse_data(self) -> dict[str, list[NinaWarningData]]:
93  """Parse warning data."""
94 
95  return_data: dict[str, list[NinaWarningData]] = {}
96 
97  for region_id, raw_warnings in self._remove_duplicate_warnings_remove_duplicate_warnings(
98  self._nina.warnings
99  ).items():
100  warnings_for_regions: list[NinaWarningData] = []
101 
102  for raw_warn in raw_warnings:
103  if re.search(
104  self.headline_filter, raw_warn.headline, flags=re.IGNORECASE
105  ):
106  _LOGGER.debug(
107  f"Ignore warning ({raw_warn.id}) by headline filter ({self.headline_filter}) with headline: {raw_warn.headline}"
108  )
109  continue
110 
111  affected_areas_string: str = ", ".join(
112  [str(area) for area in raw_warn.affected_areas]
113  )
114 
115  if not re.search(
116  self.area_filter, affected_areas_string, flags=re.IGNORECASE
117  ):
118  _LOGGER.debug(
119  f"Ignore warning ({raw_warn.id}) by area filter ({self.area_filter}) with area: {affected_areas_string}"
120  )
121  continue
122 
123  warning_data: NinaWarningData = NinaWarningData(
124  raw_warn.id,
125  raw_warn.headline,
126  raw_warn.description,
127  raw_warn.sender,
128  raw_warn.severity,
129  " ".join([str(action) for action in raw_warn.recommended_actions]),
130  affected_areas_string,
131  raw_warn.web or "",
132  raw_warn.sent or "",
133  raw_warn.start or "",
134  raw_warn.expires or "",
135  raw_warn.isValid(),
136  )
137  warnings_for_regions.append(warning_data)
138 
139  return_data[region_id] = warnings_for_regions
140 
141  return return_data
dict[str, list[NinaWarningData]] _async_update_data(self)
Definition: coordinator.py:60
None __init__(self, HomeAssistant hass, dict[str, str] regions, str headline_filter, str area_filter)
Definition: coordinator.py:48
dict[str, list[Any]] _remove_duplicate_warnings(dict[str, list[Any]] warnings)
Definition: coordinator.py:72
IssData update(pyiss.ISS iss)
Definition: __init__.py:33
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)