Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The syncthru component."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 from datetime import timedelta
7 import logging
8 
9 from pysyncthru import ConnectionMode, SyncThru, SyncThruAPINotSupported
10 
11 from homeassistant.config_entries import ConfigEntry
12 from homeassistant.const import CONF_URL, Platform
13 from homeassistant.core import HomeAssistant
14 from homeassistant.helpers import aiohttp_client, device_registry as dr
15 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
16 
17 from .const import DOMAIN
18 
19 _LOGGER = logging.getLogger(__name__)
20 
21 PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
22 
23 
24 async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
25  """Set up config entry."""
26 
27  session = aiohttp_client.async_get_clientsession(hass)
28  hass.data.setdefault(DOMAIN, {})
29  printer = SyncThru(
30  entry.data[CONF_URL], session, connection_mode=ConnectionMode.API
31  )
32 
33  async def async_update_data() -> SyncThru:
34  """Fetch data from the printer."""
35  try:
36  async with asyncio.timeout(10):
37  await printer.update()
38  except SyncThruAPINotSupported as api_error:
39  # if an exception is thrown, printer does not support syncthru
40  _LOGGER.debug(
41  "Configured printer at %s does not provide SyncThru JSON API",
42  printer.url,
43  exc_info=api_error,
44  )
45  raise
46 
47  # if the printer is offline, we raise an UpdateFailed
48  if printer.is_unknown_state():
49  raise UpdateFailed(f"Configured printer at {printer.url} does not respond.")
50  return printer
51 
52  coordinator = DataUpdateCoordinator[SyncThru](
53  hass,
54  _LOGGER,
55  config_entry=entry,
56  name=DOMAIN,
57  update_method=async_update_data,
58  update_interval=timedelta(seconds=30),
59  )
60  await coordinator.async_config_entry_first_refresh()
61  hass.data[DOMAIN][entry.entry_id] = coordinator
62  if isinstance(coordinator.last_exception, SyncThruAPINotSupported):
63  # this means that the printer does not support the syncthru JSON API
64  # and the config should simply be discarded
65  return False
66 
67  device_registry = dr.async_get(hass)
68  device_registry.async_get_or_create(
69  config_entry_id=entry.entry_id,
70  configuration_url=printer.url,
71  connections=device_connections(printer),
72  manufacturer="Samsung",
73  identifiers=device_identifiers(printer),
74  model=printer.model(),
75  name=printer.hostname(),
76  )
77 
78  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
79  return True
80 
81 
82 async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
83  """Unload the config entry."""
84  unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
85  hass.data[DOMAIN].pop(entry.entry_id, None)
86  return unload_ok
87 
88 
89 def device_identifiers(printer: SyncThru) -> set[tuple[str, str]] | None:
90  """Get device identifiers for device registry."""
91  serial = printer.serial_number()
92  if serial is None:
93  return None
94  return {(DOMAIN, serial)}
95 
96 
97 def device_connections(printer: SyncThru) -> set[tuple[str, str]]:
98  """Get device connections for device registry."""
99  if mac := printer.raw().get("identity", {}).get("mac_addr"):
100  return {(dr.CONNECTION_NETWORK_MAC, mac)}
101  return set()
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:82
set[tuple[str, str]]|None device_identifiers(SyncThru printer)
Definition: __init__.py:89
set[tuple[str, str]] device_connections(SyncThru printer)
Definition: __init__.py:97
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:24