core/homeassistant/components/fritz/device_tracker.py

107 lines
3.5 KiB
Python
Raw Normal View History

"""Support for FRITZ!Box routers."""
import logging
from fritzconnection.core import exceptions as fritzexceptions
from fritzconnection.lib.fritzhosts import FritzHosts
import voluptuous as vol
from homeassistant.components.device_tracker import (
2019-07-31 19:25:30 +00:00
DOMAIN,
PLATFORM_SCHEMA,
DeviceScanner,
)
2016-02-19 05:27:50 +00:00
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
2019-07-31 19:25:30 +00:00
CONF_DEFAULT_IP = "169.254.1.1" # This IP is valid for all FRITZ!Box routers.
2019-07-31 19:25:30 +00:00
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_HOST, default=CONF_DEFAULT_IP): cv.string,
vol.Optional(CONF_PASSWORD, default="admin"): cv.string,
vol.Optional(CONF_USERNAME, default=""): cv.string,
}
)
def get_scanner(hass, config):
2016-03-07 20:18:53 +00:00
"""Validate the configuration and return FritzBoxScanner."""
scanner = FritzBoxScanner(config[DOMAIN])
return scanner if scanner.success_init else None
class FritzBoxScanner(DeviceScanner):
2016-03-07 20:18:53 +00:00
"""This class queries a FRITZ!Box router."""
def __init__(self, config):
2016-03-07 20:18:53 +00:00
"""Initialize the scanner."""
self.last_results = []
self.host = config[CONF_HOST]
self.username = config[CONF_USERNAME]
self.password = config[CONF_PASSWORD]
self.success_init = True
2016-03-07 17:12:06 +00:00
# Establish a connection to the FRITZ!Box.
try:
self.fritz_box = FritzHosts(
2019-07-31 19:25:30 +00:00
address=self.host, user=self.username, password=self.password
)
2015-12-09 19:31:40 +00:00
except (ValueError, TypeError):
self.fritz_box = None
# At this point it is difficult to tell if a connection is established.
2016-03-07 17:12:06 +00:00
# So just check for null objects.
if self.fritz_box is None or not self.fritz_box.modelname:
self.success_init = False
if self.success_init:
2019-07-31 19:25:30 +00:00
_LOGGER.info("Successfully connected to %s", self.fritz_box.modelname)
self._update_info()
else:
2019-07-31 19:25:30 +00:00
_LOGGER.error(
"Failed to establish connection to FRITZ!Box with IP: %s", self.host
2019-07-31 19:25:30 +00:00
)
def scan_devices(self):
2016-03-07 17:12:06 +00:00
"""Scan for new devices and return a list of found device ids."""
self._update_info()
active_hosts = []
for known_host in self.last_results:
if known_host["status"] and known_host.get("mac"):
2019-07-31 19:25:30 +00:00
active_hosts.append(known_host["mac"])
return active_hosts
def get_device_name(self, device):
2016-03-07 20:18:53 +00:00
"""Return the name of the given device or None if is not known."""
2019-07-31 19:25:30 +00:00
ret = self.fritz_box.get_specific_host_entry(device).get("NewHostName")
if ret == {}:
return None
return ret
def get_extra_attributes(self, device):
"""Return the attributes (ip, mac) of the given device or None if is not known."""
ip_device = None
try:
ip_device = self.fritz_box.get_specific_host_entry(device).get(
"NewIPAddress"
)
except fritzexceptions.FritzLookUpError as fritz_lookup_error:
_LOGGER.warning(
"Host entry for %s not found: %s", device, fritz_lookup_error
)
if not ip_device:
2020-01-02 20:17:37 +00:00
return {}
return {"ip": ip_device, "mac": device}
def _update_info(self):
2016-03-07 20:18:53 +00:00
"""Retrieve latest information from the FRITZ!Box."""
if not self.success_init:
return False
_LOGGER.debug("Scanning")
self.last_results = self.fritz_box.get_hosts_info()
return True