ha-core/homeassistant/components/luci/device_tracker.py

109 lines
3.3 KiB
Python
Raw Normal View History

"""Support for OpenWRT (luci) routers."""
from __future__ import annotations
import logging
2019-04-10 14:35:57 +02:00
2019-12-04 11:13:22 +01:00
from openwrt_luci_rpc import OpenWrtRpc
import voluptuous as vol
from homeassistant.components.device_tracker import (
2019-07-31 21:25:30 +02:00
DOMAIN,
PLATFORM_SCHEMA as PARENT_PLATFORM_SCHEMA,
2019-07-31 21:25:30 +02:00
DeviceScanner,
)
from homeassistant.const import (
CONF_HOST,
CONF_PASSWORD,
CONF_SSL,
CONF_USERNAME,
CONF_VERIFY_SSL,
)
from homeassistant.core import HomeAssistant
2019-04-10 14:35:57 +02:00
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType
_LOGGER = logging.getLogger(__name__)
DEFAULT_SSL = False
DEFAULT_VERIFY_SSL = True
PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend(
2019-07-31 21:25:30 +02:00
{
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_SSL, default=DEFAULT_SSL): cv.boolean,
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
2019-07-31 21:25:30 +02:00
}
)
def get_scanner(hass: HomeAssistant, config: ConfigType) -> LuciDeviceScanner | None:
2016-03-07 21:18:53 +01:00
"""Validate the configuration and return a Luci scanner."""
scanner = LuciDeviceScanner(config[DOMAIN])
return scanner if scanner.success_init else None
class LuciDeviceScanner(DeviceScanner):
"""This class scans for devices connected to an OpenWrt router."""
2016-03-07 21:18:53 +01:00
def __init__(self, config):
2016-03-07 21:18:53 +01:00
"""Initialize the scanner."""
2019-04-10 14:35:57 +02:00
self.router = OpenWrtRpc(
2019-07-31 21:25:30 +02:00
config[CONF_HOST],
config[CONF_USERNAME],
config[CONF_PASSWORD],
config[CONF_SSL],
config[CONF_VERIFY_SSL],
2019-07-31 21:25:30 +02:00
)
self.last_results = {}
self.success_init = self.router.is_logged_in()
def scan_devices(self):
2016-03-07 21:18:53 +01:00
"""Scan for new devices and return a list with found device IDs."""
self._update_info()
return [device.mac for device in self.last_results]
def get_device_name(self, device):
2016-03-07 21:18:53 +01:00
"""Return the name of the given device or None if we don't know."""
2019-07-31 21:25:30 +02:00
name = next(
(result.hostname for result in self.last_results if result.mac == device),
None,
)
return name
def get_extra_attributes(self, device):
2023-02-03 23:08:48 +01:00
"""Get extra attributes of a device.
Some known extra attributes that may be returned in the device tuple
2019-04-10 14:35:57 +02:00
include MAC address (mac), network device (dev), IP address
(ip), reachable status (reachable), associated router
(host), hostname if known (hostname) among others.
"""
2019-07-31 21:25:30 +02:00
device = next(
(result for result in self.last_results if result.mac == device), None
)
return device._asdict()
def _update_info(self):
"""Check the Luci router for devices."""
2019-07-31 21:25:30 +02:00
result = self.router.get_all_connected_devices(only_reachable=True)
2019-04-10 14:35:57 +02:00
_LOGGER.debug("Luci get_all_connected_devices returned: %s", result)
last_results = []
for device in result:
if (
not hasattr(self.router.router.owrt_version, "release")
or not self.router.router.owrt_version.release
or self.router.router.owrt_version.release[0] < 19
or device.reachable
):
last_results.append(device)
self.last_results = last_results