1 """Support for Tomato routers."""
3 from __future__
import annotations
5 from http
import HTTPStatus
11 import voluptuous
as vol
14 DOMAIN
as DEVICE_TRACKER_DOMAIN,
15 PLATFORM_SCHEMA
as DEVICE_TRACKER_PLATFORM_SCHEMA,
30 CONF_HTTP_ID =
"http_id"
32 _LOGGER = logging.getLogger(__name__)
34 PLATFORM_SCHEMA = DEVICE_TRACKER_PLATFORM_SCHEMA.extend(
36 vol.Required(CONF_HOST): cv.string,
37 vol.Optional(CONF_PORT): cv.port,
38 vol.Optional(CONF_SSL, default=
False): cv.boolean,
39 vol.Optional(CONF_VERIFY_SSL, default=
True): vol.Any(cv.boolean, cv.isfile),
40 vol.Required(CONF_PASSWORD): cv.string,
41 vol.Required(CONF_USERNAME): cv.string,
42 vol.Required(CONF_HTTP_ID): cv.string,
47 def get_scanner(hass: HomeAssistant, config: ConfigType) -> TomatoDeviceScanner:
48 """Validate the configuration and returns a Tomato scanner."""
53 """Class which queries a wireless router running Tomato firmware."""
56 """Initialize the scanner."""
57 host, http_id = config[CONF_HOST], config[CONF_HTTP_ID]
58 port = config.get(CONF_PORT)
59 username, password = config[CONF_USERNAME], config[CONF_PASSWORD]
60 self.ssl, self.
verify_sslverify_ssl = config[CONF_SSL], config[CONF_VERIFY_SSL]
62 port = 443
if self.ssl
else 80
64 protocol =
"https" if self.ssl
else "http"
65 self.
reqreq = requests.Request(
67 f
"{protocol}://{host}:{port}/update.cgi",
68 data={
"_http_id": http_id,
"exec":
"devlist"},
69 auth=requests.auth.HTTPBasicAuth(username, password),
79 """Scan for new devices and return a list with found device IDs."""
82 return [item[1]
for item
in self.
last_resultslast_results[
"wldev"]]
85 """Return the name of the given device or None if we don't know."""
87 item[0]
for item
in self.
last_resultslast_results[
"dhcpd_lease"]
if item[2] == device
90 if not filter_named
or not filter_named[0]:
93 return filter_named[0]
96 """Ensure the information from the Tomato router is up to date.
98 Return boolean if scanning successful.
100 _LOGGER.debug(
"Scanning")
104 response = requests.Session().send(
108 response = requests.Session().send(self.
reqreq, timeout=60)
112 if response.status_code == HTTPStatus.OK:
113 for param, value
in self.
parse_api_patternparse_api_pattern.findall(response.text):
114 if param
in (
"wldev",
"dhcpd_lease"):
115 self.
last_resultslast_results[param] = json.loads(value.replace(
"'",
'"'))
118 if response.status_code == HTTPStatus.UNAUTHORIZED:
121 "Failed to authenticate, please check your username and password"
125 except requests.exceptions.ConnectionError:
129 "Failed to connect to the router or invalid http_id supplied"
133 except requests.exceptions.Timeout:
136 _LOGGER.exception(
"Connection to the router timed out")
141 _LOGGER.exception(
"Failed to parse response from router")
def __init__(self, config)
def _update_tomato_info(self)
def get_device_name(self, device)
TomatoDeviceScanner get_scanner(HomeAssistant hass, ConfigType config)