Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The NextDNS component."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 from dataclasses import dataclass
7 from datetime import timedelta
8 
9 from aiohttp.client_exceptions import ClientConnectorError
10 from nextdns import (
11  AnalyticsDnssec,
12  AnalyticsEncryption,
13  AnalyticsIpVersions,
14  AnalyticsProtocols,
15  AnalyticsStatus,
16  ApiError,
17  ConnectionStatus,
18  InvalidApiKeyError,
19  NextDns,
20  Settings,
21 )
22 from tenacity import RetryError
23 
24 from homeassistant.config_entries import ConfigEntry
25 from homeassistant.const import CONF_API_KEY, Platform
26 from homeassistant.core import HomeAssistant
27 from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
28 from homeassistant.helpers.aiohttp_client import async_get_clientsession
29 
30 from .const import (
31  ATTR_CONNECTION,
32  ATTR_DNSSEC,
33  ATTR_ENCRYPTION,
34  ATTR_IP_VERSIONS,
35  ATTR_PROTOCOLS,
36  ATTR_SETTINGS,
37  ATTR_STATUS,
38  CONF_PROFILE_ID,
39  UPDATE_INTERVAL_ANALYTICS,
40  UPDATE_INTERVAL_CONNECTION,
41  UPDATE_INTERVAL_SETTINGS,
42 )
43 from .coordinator import (
44  NextDnsConnectionUpdateCoordinator,
45  NextDnsDnssecUpdateCoordinator,
46  NextDnsEncryptionUpdateCoordinator,
47  NextDnsIpVersionsUpdateCoordinator,
48  NextDnsProtocolsUpdateCoordinator,
49  NextDnsSettingsUpdateCoordinator,
50  NextDnsStatusUpdateCoordinator,
51  NextDnsUpdateCoordinator,
52 )
53 
54 type NextDnsConfigEntry = ConfigEntry[NextDnsData]
55 
56 
57 @dataclass
59  """Data for the NextDNS integration."""
60 
61  connection: NextDnsUpdateCoordinator[ConnectionStatus]
62  dnssec: NextDnsUpdateCoordinator[AnalyticsDnssec]
63  encryption: NextDnsUpdateCoordinator[AnalyticsEncryption]
64  ip_versions: NextDnsUpdateCoordinator[AnalyticsIpVersions]
65  protocols: NextDnsUpdateCoordinator[AnalyticsProtocols]
66  settings: NextDnsUpdateCoordinator[Settings]
67  status: NextDnsUpdateCoordinator[AnalyticsStatus]
68 
69 
70 PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.SENSOR, Platform.SWITCH]
71 COORDINATORS: list[tuple[str, type[NextDnsUpdateCoordinator], timedelta]] = [
72  (ATTR_CONNECTION, NextDnsConnectionUpdateCoordinator, UPDATE_INTERVAL_CONNECTION),
73  (ATTR_DNSSEC, NextDnsDnssecUpdateCoordinator, UPDATE_INTERVAL_ANALYTICS),
74  (ATTR_ENCRYPTION, NextDnsEncryptionUpdateCoordinator, UPDATE_INTERVAL_ANALYTICS),
75  (ATTR_IP_VERSIONS, NextDnsIpVersionsUpdateCoordinator, UPDATE_INTERVAL_ANALYTICS),
76  (ATTR_PROTOCOLS, NextDnsProtocolsUpdateCoordinator, UPDATE_INTERVAL_ANALYTICS),
77  (ATTR_SETTINGS, NextDnsSettingsUpdateCoordinator, UPDATE_INTERVAL_SETTINGS),
78  (ATTR_STATUS, NextDnsStatusUpdateCoordinator, UPDATE_INTERVAL_ANALYTICS),
79 ]
80 
81 
82 async def async_setup_entry(hass: HomeAssistant, entry: NextDnsConfigEntry) -> bool:
83  """Set up NextDNS as config entry."""
84  api_key = entry.data[CONF_API_KEY]
85  profile_id = entry.data[CONF_PROFILE_ID]
86 
87  websession = async_get_clientsession(hass)
88  try:
89  nextdns = await NextDns.create(websession, api_key)
90  except (ApiError, ClientConnectorError, RetryError, TimeoutError) as err:
91  raise ConfigEntryNotReady from err
92  except InvalidApiKeyError as err:
93  raise ConfigEntryAuthFailed from err
94 
95  tasks = []
96  coordinators = {}
97 
98  # Independent DataUpdateCoordinator is used for each API endpoint to avoid
99  # unnecessary requests when entities using this endpoint are disabled.
100  for coordinator_name, coordinator_class, update_interval in COORDINATORS:
101  coordinator = coordinator_class(hass, nextdns, profile_id, update_interval)
102  tasks.append(coordinator.async_config_entry_first_refresh())
103  coordinators[coordinator_name] = coordinator
104 
105  await asyncio.gather(*tasks)
106 
107  entry.runtime_data = NextDnsData(**coordinators)
108 
109  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
110 
111  return True
112 
113 
114 async def async_unload_entry(hass: HomeAssistant, entry: NextDnsConfigEntry) -> bool:
115  """Unload a config entry."""
116  return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
bool async_setup_entry(HomeAssistant hass, NextDnsConfigEntry entry)
Definition: __init__.py:82
bool async_unload_entry(HomeAssistant hass, NextDnsConfigEntry entry)
Definition: __init__.py:114
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)