Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

device tracker - tomato https support #11566

Merged
merged 13 commits into from
Jan 24, 2018
35 changes: 25 additions & 10 deletions homeassistant/components/device_tracker/tomato.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,20 @@
import homeassistant.helpers.config_validation as cv
from homeassistant.components.device_tracker import (
DOMAIN, PLATFORM_SCHEMA, DeviceScanner)
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.const import (
CONF_HOST, CONF_PORT, CONF_SSL, CONF_VERIFY_SSL,
CONF_PASSWORD, CONF_USERNAME)

CONF_HTTP_ID = 'http_id'

_LOGGER = logging.getLogger(__name__)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_PORT, default=80): cv.port,
vol.Optional(CONF_SSL, default=False): cv.boolean,
vol.Optional(CONF_VERIFY_SSL, default=True): vol.Any(
cv.boolean, cv.isfile),
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_HTTP_ID): cv.string
Expand All @@ -39,16 +45,19 @@ class TomatoDeviceScanner(DeviceScanner):
def __init__(self, config):
"""Initialize the scanner."""
host, http_id = config[CONF_HOST], config[CONF_HTTP_ID]
port = config[CONF_PORT]
username, password = config[CONF_USERNAME], config[CONF_PASSWORD]
self.ssl, self.verify_ssl = config[CONF_SSL], config[CONF_VERIFY_SSL]

self.req = requests.Request(
'POST', 'http://{}/update.cgi'.format(host),
'POST', 'http{}://{}:{}/update.cgi'.format(
"s" if self.ssl else "", host, port
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If ssl is true, port still defaults to 80. Is that what you were expecting?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I hadn't even really thought much about that to be honest. I'll throw a small update in for that so that it'll default to 80 or 443 depending on if there is/isn't ssl enabled.

),
data={'_http_id': http_id, 'exec': 'devlist'},
auth=requests.auth.HTTPBasicAuth(username, password)).prepare()

self.parse_api_pattern = re.compile(r"(?P<param>\w*) = (?P<value>.*);")

self.logger = logging.getLogger("{}.{}".format(__name__, "Tomato"))
self.last_results = {"wldev": [], "dhcpd_lease": []}

self.success_init = self._update_tomato_info()
Expand All @@ -74,10 +83,16 @@ def _update_tomato_info(self):

Return boolean if scanning successful.
"""
self.logger.info("Scanning")
_LOGGER.info("Scanning")

try:
response = requests.Session().send(self.req, timeout=3)
if self.ssl:
response = requests.Session().send(self.req,
timeout=3,
verify=self.verify_ssl)
else:
response = requests.Session().send(self.req, timeout=3)

# Calling and parsing the Tomato api here. We only need the
# wldev and dhcpd_lease values.
if response.status_code == 200:
Expand All @@ -92,25 +107,25 @@ def _update_tomato_info(self):

elif response.status_code == 401:
# Authentication error
self.logger.exception((
_LOGGER.exception((
"Failed to authenticate, "
"please check your username and password"))
return False

except requests.exceptions.ConnectionError:
# We get this if we could not connect to the router or
# an invalid http_id was supplied.
self.logger.exception("Failed to connect to the router or "
"invalid http_id supplied")
_LOGGER.exception("Failed to connect to the router or "
"invalid http_id supplied")
return False

except requests.exceptions.Timeout:
# We get this if we could not connect to the router or
# an invalid http_id was supplied.
self.logger.exception("Connection to the router timed out")
_LOGGER.exception("Connection to the router timed out")
return False

except ValueError:
# If JSON decoder could not parse the response.
self.logger.exception("Failed to parse response from router")
_LOGGER.exception("Failed to parse response from router")
return False
Loading