Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """Integrate with FreeDNS Dynamic DNS service at freedns.afraid.org."""
2 
3 import asyncio
4 from datetime import datetime, timedelta
5 import logging
6 
7 import aiohttp
8 import voluptuous as vol
9 
10 from homeassistant.const import CONF_ACCESS_TOKEN, CONF_SCAN_INTERVAL, CONF_URL
11 from homeassistant.core import HomeAssistant
12 from homeassistant.helpers.aiohttp_client import async_get_clientsession
14 from homeassistant.helpers.event import async_track_time_interval
15 from homeassistant.helpers.typing import ConfigType
16 
17 _LOGGER = logging.getLogger(__name__)
18 
19 DOMAIN = "freedns"
20 
21 DEFAULT_INTERVAL = timedelta(minutes=10)
22 
23 TIMEOUT = 10
24 UPDATE_URL = "https://freedns.afraid.org/dynamic/update.php"
25 
26 CONFIG_SCHEMA = vol.Schema(
27  {
28  DOMAIN: vol.Schema(
29  {
30  vol.Exclusive(CONF_URL, DOMAIN): cv.string,
31  vol.Exclusive(CONF_ACCESS_TOKEN, DOMAIN): cv.string,
32  vol.Optional(CONF_SCAN_INTERVAL, default=DEFAULT_INTERVAL): vol.All(
33  cv.time_period, cv.positive_timedelta
34  ),
35  }
36  )
37  },
38  extra=vol.ALLOW_EXTRA,
39 )
40 
41 
42 async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
43  """Initialize the FreeDNS component."""
44  conf = config[DOMAIN]
45  url = conf.get(CONF_URL)
46  auth_token = conf.get(CONF_ACCESS_TOKEN)
47  update_interval = conf[CONF_SCAN_INTERVAL]
48 
49  session = async_get_clientsession(hass)
50 
51  result = await _update_freedns(hass, session, url, auth_token)
52 
53  if result is False:
54  return False
55 
56  async def update_domain_callback(now: datetime) -> None:
57  """Update the FreeDNS entry."""
58  await _update_freedns(hass, session, url, auth_token)
59 
61  hass, update_domain_callback, update_interval, cancel_on_shutdown=True
62  )
63 
64  return True
65 
66 
67 async def _update_freedns(hass, session, url, auth_token):
68  """Update FreeDNS."""
69  params = None
70 
71  if url is None:
72  url = UPDATE_URL
73 
74  if auth_token is not None:
75  params = {}
76  params[auth_token] = ""
77 
78  try:
79  async with asyncio.timeout(TIMEOUT):
80  resp = await session.get(url, params=params)
81  body = await resp.text()
82 
83  if "has not changed" in body:
84  # IP has not changed.
85  _LOGGER.debug("FreeDNS update skipped: IP has not changed")
86  return True
87 
88  if "ERROR" not in body:
89  _LOGGER.debug("Updating FreeDNS was successful: %s", body)
90  return True
91 
92  if "Invalid update URL" in body:
93  _LOGGER.error("FreeDNS update token is invalid")
94  else:
95  _LOGGER.warning("Updating FreeDNS failed: %s", body)
96 
97  except aiohttp.ClientError:
98  _LOGGER.warning("Can't connect to FreeDNS API")
99 
100  except TimeoutError:
101  _LOGGER.warning("Timeout from FreeDNS API at %s", url)
102 
103  return False
bool async_setup(HomeAssistant hass, ConfigType config)
Definition: __init__.py:42
def _update_freedns(hass, session, url, auth_token)
Definition: __init__.py:67
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)
CALLBACK_TYPE async_track_time_interval(HomeAssistant hass, Callable[[datetime], Coroutine[Any, Any, None]|None] action, timedelta interval, *str|None name=None, bool|None cancel_on_shutdown=None)
Definition: event.py:1679