-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
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
Fix bt_home_hub_5 device tracker #15096
Changes from 6 commits
f4e8b4f
cfd9ea4
9cced7d
daf36ea
c3696b9
9434316
36ddf79
3aa41ef
a598a49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,22 +4,20 @@ | |
For more details about this platform, please refer to the documentation at | ||
https://home-assistant.io/components/device_tracker.bt_home_hub_5/ | ||
""" | ||
|
||
import logging | ||
import re | ||
import xml.etree.ElementTree as ET | ||
import json | ||
from urllib.parse import unquote | ||
|
||
import requests | ||
import voluptuous as vol | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a blank line between standard library and 3rd party imports. |
||
|
||
import homeassistant.helpers.config_validation as cv | ||
from homeassistant.components.device_tracker import ( | ||
DOMAIN, PLATFORM_SCHEMA, DeviceScanner) | ||
from homeassistant.components.device_tracker import (DOMAIN, PLATFORM_SCHEMA, | ||
DeviceScanner) | ||
from homeassistant.const import CONF_HOST | ||
|
||
REQUIREMENTS = ['bthomehub5-devicelist==0.1.1'] | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
_MAC_REGEX = re.compile(r'(([0-9A-Fa-f]{1,2}\:){5}[0-9A-Fa-f]{1,2})') | ||
_MAC_REGEX = re.compile(r'(([0-9A-Fa-f]{1,2}:){5}[0-9A-Fa-f]{1,2})') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't used anymore. |
||
|
||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ | ||
vol.Required(CONF_HOST): cv.string | ||
|
@@ -37,44 +35,47 @@ class BTHomeHub5DeviceScanner(DeviceScanner): | |
"""This class queries a BT Home Hub 5.""" | ||
|
||
def __init__(self, config): | ||
import bthomehub5_devicelist | ||
|
||
"""Initialise the scanner.""" | ||
_LOGGER.info("Initialising BT Home Hub 5") | ||
self.host = config.get(CONF_HOST, '192.168.1.254') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move the default value to the config schema. |
||
self.last_results = {} | ||
self.url = 'http://{}/nonAuth/home_status.xml'.format(self.host) | ||
|
||
# Test the router is accessible | ||
data = _get_homehub_data(self.url) | ||
data = bthomehub5_devicelist.get_devicelist(self.host) | ||
self.success_init = data is not None | ||
|
||
def scan_devices(self): | ||
"""Scan for new devices and return a list with found device IDs.""" | ||
self._update_info() | ||
self.update_info() | ||
|
||
return (device 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.""" | ||
# If not initialised and not already scanned and not found. | ||
if device not in self.last_results: | ||
self._update_info() | ||
self.update_info() | ||
|
||
if not self.last_results: | ||
return None | ||
|
||
return self.last_results.get(device) | ||
|
||
def _update_info(self): | ||
def update_info(self): | ||
"""Ensure the information from the BT Home Hub 5 is up to date. | ||
|
||
Return boolean if scanning successful. | ||
""" | ||
|
||
import bthomehub5_devicelist | ||
|
||
if not self.success_init: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like it can be removed. |
||
return False | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nothing is checking this return value. |
||
|
||
_LOGGER.info("Scanning") | ||
|
||
data = _get_homehub_data(self.url) | ||
data = bthomehub5_devicelist.get_devicelist(self.host) | ||
|
||
if not data: | ||
_LOGGER.warning("Error scanning devices") | ||
|
@@ -83,45 +84,3 @@ def _update_info(self): | |
self.last_results = data | ||
|
||
return True | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. |
||
|
||
|
||
def _get_homehub_data(url): | ||
"""Retrieve data from BT Home Hub 5 and return parsed result.""" | ||
try: | ||
response = requests.get(url, timeout=5) | ||
except requests.exceptions.Timeout: | ||
_LOGGER.exception("Connection to the router timed out") | ||
return | ||
if response.status_code == 200: | ||
return _parse_homehub_response(response.text) | ||
_LOGGER.error("Invalid response from Home Hub: %s", response) | ||
|
||
|
||
def _parse_homehub_response(data_str): | ||
"""Parse the BT Home Hub 5 data format.""" | ||
root = ET.fromstring(data_str) | ||
|
||
dirty_json = root.find('known_device_list').get('value') | ||
|
||
# Normalise the JavaScript data to JSON. | ||
clean_json = unquote(dirty_json.replace('\'', '\"') | ||
.replace('{', '{\"') | ||
.replace(':\"', '\":\"') | ||
.replace('\",', '\",\"')) | ||
|
||
known_devices = [x for x in json.loads(clean_json) if x] | ||
|
||
devices = {} | ||
|
||
for device in known_devices: | ||
name = device.get('name') | ||
mac = device.get('mac') | ||
|
||
if _MAC_REGEX.match(mac) or ',' in mac: | ||
for mac_addr in mac.split(','): | ||
if _MAC_REGEX.match(mac_addr): | ||
devices[mac_addr] = name | ||
else: | ||
devices[mac] = name | ||
|
||
return devices |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this blank line.