Home Assistant Unofficial Reference 2024.12.1
device_tracker.py
Go to the documentation of this file.
1 """Support for OpenWRT (luci) routers."""
2 
3 from __future__ import annotations
4 
5 import logging
6 
7 from openwrt_luci_rpc import OpenWrtRpc
8 import voluptuous as vol
9 
11  DOMAIN as DEVICE_TRACKER_DOMAIN,
12  PLATFORM_SCHEMA as DEVICE_TRACKER_PLATFORM_SCHEMA,
13  DeviceScanner,
14 )
15 from homeassistant.const import (
16  CONF_HOST,
17  CONF_PASSWORD,
18  CONF_SSL,
19  CONF_USERNAME,
20  CONF_VERIFY_SSL,
21 )
22 from homeassistant.core import HomeAssistant
24 from homeassistant.helpers.typing import ConfigType
25 
26 _LOGGER = logging.getLogger(__name__)
27 
28 DEFAULT_SSL = False
29 DEFAULT_VERIFY_SSL = True
30 
31 PLATFORM_SCHEMA = DEVICE_TRACKER_PLATFORM_SCHEMA.extend(
32  {
33  vol.Required(CONF_HOST): cv.string,
34  vol.Required(CONF_USERNAME): cv.string,
35  vol.Required(CONF_PASSWORD): cv.string,
36  vol.Optional(CONF_SSL, default=DEFAULT_SSL): cv.boolean,
37  vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
38  }
39 )
40 
41 
42 def get_scanner(hass: HomeAssistant, config: ConfigType) -> LuciDeviceScanner | None:
43  """Validate the configuration and return a Luci scanner."""
44  scanner = LuciDeviceScanner(config[DEVICE_TRACKER_DOMAIN])
45 
46  return scanner if scanner.success_init else None
47 
48 
49 class LuciDeviceScanner(DeviceScanner):
50  """Scanner for devices connected to an OpenWrt router."""
51 
52  def __init__(self, config):
53  """Initialize the scanner."""
54 
55  self.routerrouter = OpenWrtRpc(
56  config[CONF_HOST],
57  config[CONF_USERNAME],
58  config[CONF_PASSWORD],
59  config[CONF_SSL],
60  config[CONF_VERIFY_SSL],
61  )
62 
63  self.last_resultslast_results = {}
64  self.success_initsuccess_init = self.routerrouter.is_logged_in()
65 
66  def scan_devices(self):
67  """Scan for new devices and return a list with found device IDs."""
68  self._update_info_update_info()
69 
70  return [device.mac for device in self.last_resultslast_results]
71 
72  def get_device_name(self, device):
73  """Return the name of the given device or None if we don't know."""
74  return next(
75  (result.hostname for result in self.last_resultslast_results if result.mac == device),
76  None,
77  )
78 
79  def get_extra_attributes(self, device):
80  """Get extra attributes of a device.
81 
82  Some known extra attributes that may be returned in the device tuple
83  include MAC address (mac), network device (dev), IP address
84  (ip), reachable status (reachable), associated router
85  (host), hostname if known (hostname) among others.
86  """
87  device = next(
88  (result for result in self.last_resultslast_results if result.mac == device), None
89  )
90  return device._asdict()
91 
92  def _update_info(self):
93  """Check the Luci router for devices."""
94  result = self.routerrouter.get_all_connected_devices(only_reachable=True)
95 
96  _LOGGER.debug("Luci get_all_connected_devices returned: %s", result)
97 
98  self.last_resultslast_results = [
99  device
100  for device in result
101  if not hasattr(self.routerrouter.router.owrt_version, "release")
102  or not self.routerrouter.router.owrt_version.release
103  or self.routerrouter.router.owrt_version.release[0] < 19
104  or device.reachable
105  ]
LuciDeviceScanner|None get_scanner(HomeAssistant hass, ConfigType config)