core/homeassistant/components/device_tracker/tplink.py

118 lines
3.2 KiB
Python
Raw Normal View History

2015-06-17 20:55:03 +00:00
"""
homeassistant.components.device_tracker.tplink
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Device tracker platform that supports scanning a TP-Link router for device
presence.
Configuration:
To use the TP-Link tracker you will need to add something like the following
to your config/configuration.yaml
device_tracker:
platform: tplink
host: YOUR_ROUTER_IP
username: YOUR_ADMIN_USERNAME
password: YOUR_ADMIN_PASSWORD
Variables:
host
*Required
The IP address of your router, e.g. 192.168.1.1.
username
*Required
The username of an user with administrative privileges, usually 'admin'.
password
*Required
The password for your given admin account.
"""
import logging
from datetime import timedelta
import re
import threading
import requests
from homeassistant.const import CONF_HOST, CONF_USERNAME, CONF_PASSWORD
from homeassistant.helpers import validate_config
from homeassistant.util import Throttle
from homeassistant.components.device_tracker import DOMAIN
# Return cached results if last scan was less then this time ago
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5)
_LOGGER = logging.getLogger(__name__)
def get_scanner(hass, config):
""" Validates config and returns a TP-Link scanner. """
if not validate_config(config,
{DOMAIN: [CONF_HOST, CONF_USERNAME, CONF_PASSWORD]},
_LOGGER):
return None
scanner = TplinkDeviceScanner(config[DOMAIN])
return scanner if scanner.success_init else None
class TplinkDeviceScanner(object):
""" This class queries a wireless router running TP-Link firmware
for connected devices.
"""
def __init__(self, config):
host = config[CONF_HOST]
username, password = config[CONF_USERNAME], config[CONF_PASSWORD]
2015-06-17 21:40:58 +00:00
self.parse_macs = re.compile('[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-' +
2015-06-17 21:32:33 +00:00
'[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}')
2015-06-17 20:55:03 +00:00
self.host = host
self.username = username
self.password = password
self.last_results = {}
self.lock = threading.Lock()
self.success_init = self._update_info()
def scan_devices(self):
""" Scans for new devices and return a
list containing found device ids. """
self._update_info()
return self.last_results
# pylint: disable=no-self-use
2015-06-17 20:55:03 +00:00
def get_device_name(self, device):
2015-06-17 21:40:58 +00:00
""" The TP-Link firmware doesn't save the name of the wireless
2015-06-17 21:32:33 +00:00
device. """
2015-06-17 20:55:03 +00:00
return None
@Throttle(MIN_TIME_BETWEEN_SCANS)
def _update_info(self):
""" Ensures the information from the TP-Link router is up to date.
Returns boolean if scanning successful. """
with self.lock:
_LOGGER.info("Loading wireless clients...")
url = 'http://{}/userRpm/WlanStationRpm.htm'.format(self.host)
referer = 'http://{}'.format(self.host)
2015-06-17 21:32:33 +00:00
page = requests.get(url, auth=(self.username, self.password),
headers={'referer': referer})
2015-06-17 20:55:03 +00:00
result = self.parse_macs.findall(page.text)
2015-06-17 21:32:33 +00:00
2015-06-17 20:55:03 +00:00
if result:
self.last_results = [mac.replace("-", ":") for mac in result]
2015-06-17 20:55:03 +00:00
return True
return False