"""Support for French FAI Bouygues Bbox routers.""" from __future__ import annotations from collections import namedtuple from datetime import timedelta import logging import pybbox import voluptuous as vol from homeassistant.components.device_tracker import ( DOMAIN, PLATFORM_SCHEMA as PARENT_PLATFORM_SCHEMA, DeviceScanner, ) from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant import homeassistant.helpers.config_validation as cv from homeassistant.helpers.typing import ConfigType from homeassistant.util import Throttle import homeassistant.util.dt as dt_util _LOGGER = logging.getLogger(__name__) DEFAULT_HOST = "192.168.1.254" MIN_TIME_BETWEEN_SCANS = timedelta(seconds=60) PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend( {vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string} ) def get_scanner(hass: HomeAssistant, config: ConfigType) -> DeviceScanner | None: """Validate the configuration and return a Bbox scanner.""" scanner = BboxDeviceScanner(config[DOMAIN]) return scanner if scanner.success_init else None Device = namedtuple("Device", ["mac", "name", "ip", "last_update"]) class BboxDeviceScanner(DeviceScanner): """This class scans for devices connected to the bbox.""" def __init__(self, config): """Get host from config.""" self.host = config[CONF_HOST] """Initialize the scanner.""" self.last_results: list[Device] = [] self.success_init = self._update_info() _LOGGER.info("Scanner initialized") def scan_devices(self): """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): """Return the name of the given device or None if we don't know.""" filter_named = [ result.name for result in self.last_results if result.mac == device ] if filter_named: return filter_named[0] return None @Throttle(MIN_TIME_BETWEEN_SCANS) def _update_info(self): """Check the Bbox for devices. Returns boolean if scanning successful. """ _LOGGER.info("Scanning") box = pybbox.Bbox(ip=self.host) result = box.get_all_connected_devices() now = dt_util.now() last_results = [] for device in result: if device["active"] != 1: continue last_results.append( Device( device["macaddress"], device["hostname"], device["ipaddress"], now ) ) self.last_results = last_results _LOGGER.info("Scan successful") return True