core/homeassistant/components/tellduslive.py

187 lines
6.5 KiB
Python
Raw Normal View History

"""
homeassistant.components.tellduslive
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2016-02-02 23:35:53 +00:00
Tellduslive Component.
2016-02-02 23:35:53 +00:00
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/tellduslive/
"""
from datetime import timedelta
import logging
from homeassistant.loader import get_component
from homeassistant import bootstrap
from homeassistant.util import Throttle
from homeassistant.helpers import validate_config
from homeassistant.const import (
EVENT_PLATFORM_DISCOVERED, ATTR_SERVICE, ATTR_DISCOVERED)
DOMAIN = "tellduslive"
DISCOVER_SWITCHES = "tellduslive.switches"
DISCOVER_SENSORS = "tellduslive.sensors"
CONF_PUBLIC_KEY = "public_key"
CONF_PRIVATE_KEY = "private_key"
CONF_TOKEN = "token"
CONF_TOKEN_SECRET = "token_secret"
REQUIREMENTS = ['tellive-py==0.5.2']
_LOGGER = logging.getLogger(__name__)
NETWORK = None
# Return cached results if last scan was less then this time ago
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=600)
class TelldusLiveData(object):
""" Gets the latest data and update the states. """
def __init__(self, hass, config):
public_key = config[DOMAIN].get(CONF_PUBLIC_KEY)
private_key = config[DOMAIN].get(CONF_PRIVATE_KEY)
token = config[DOMAIN].get(CONF_TOKEN)
token_secret = config[DOMAIN].get(CONF_TOKEN_SECRET)
from tellive.client import LiveClient
from tellive.live import TelldusLive
self._sensors = []
self._switches = []
self._client = LiveClient(public_key=public_key,
private_key=private_key,
access_token=token,
access_secret=token_secret)
self._api = TelldusLive(self._client)
def update(self, hass, config):
2016-02-02 23:35:53 +00:00
""" Send discovery event if component not yet discovered. """
self._update_sensors()
self._update_switches()
for component_name, found_devices, discovery_type in \
(('sensor', self._sensors, DISCOVER_SENSORS),
('switch', self._switches, DISCOVER_SWITCHES)):
if len(found_devices):
component = get_component(component_name)
bootstrap.setup_component(hass, component.DOMAIN, config)
hass.bus.fire(EVENT_PLATFORM_DISCOVERED,
{ATTR_SERVICE: discovery_type,
ATTR_DISCOVERED: {}})
def _request(self, what, **params):
2016-02-02 23:35:53 +00:00
""" Sends a request to the Tellstick Live API. """
from tellive.live import const
supported_methods = const.TELLSTICK_TURNON \
| const.TELLSTICK_TURNOFF \
| const.TELLSTICK_TOGGLE
default_params = {'supportedMethods': supported_methods,
"includeValues": 1,
"includeScale": 1}
params.update(default_params)
# room for improvement: the telllive library doesn't seem to
# re-use sessions, instead it opens a new session for each request
# this needs to be fixed
response = self._client.request(what, params)
return response
def check_request(self, what, **params):
2016-02-02 23:35:53 +00:00
""" Make request, check result if successful. """
2015-12-27 20:47:49 +00:00
response = self._request(what, **params)
return response['status'] == "success"
def validate_session(self):
2016-02-02 23:35:53 +00:00
""" Make a dummy request to see if the session is valid. """
try:
response = self._request("user/profile")
return 'email' in response
except RuntimeError:
return False
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def _update_sensors(self):
2016-02-02 23:35:53 +00:00
""" Get the latest sensor data from Telldus Live. """
_LOGGER.info("Updating sensors from Telldus Live")
self._sensors = self._request("sensors/list")["sensor"]
def _update_switches(self):
2016-02-02 23:35:53 +00:00
""" Get the configured switches from Telldus Live. """
_LOGGER.info("Updating switches from Telldus Live")
self._switches = self._request("devices/list")["device"]
# filter out any group of switches
self._switches = [switch for switch in self._switches
if switch["type"] == "device"]
def get_sensors(self):
2016-02-02 23:35:53 +00:00
""" Get the configured sensors. """
self._update_sensors()
return self._sensors
def get_switches(self):
2016-02-02 23:35:53 +00:00
""" Get the configured switches. """
self._update_switches()
return self._switches
def get_sensor_value(self, sensor_id, sensor_name):
2016-02-02 23:35:53 +00:00
""" Get the latest (possibly cached) sensor value. """
self._update_sensors()
for component in self._sensors:
if component["id"] == sensor_id:
for sensor in component["data"]:
if sensor["name"] == sensor_name:
return (sensor["value"],
component["battery"],
component["lastUpdated"])
def get_switch_state(self, switch_id):
2016-02-02 23:35:53 +00:00
""" Returns the state of an switch. """
_LOGGER.info("Updating switch state from Telldus Live")
2015-12-27 20:47:49 +00:00
response = self._request("device/info", id=switch_id)["state"]
return int(response)
def turn_switch_on(self, switch_id):
2016-02-02 23:35:53 +00:00
""" Turn switch off. """
return self.check_request("device/turnOn", id=switch_id)
def turn_switch_off(self, switch_id):
2016-02-02 23:35:53 +00:00
""" Turn switch on. """
return self.check_request("device/turnOff", id=switch_id)
def setup(hass, config):
2016-02-02 23:35:53 +00:00
""" Setup the Telldus Live component. """
# fixme: aquire app key and provide authentication
# using username + password
if not validate_config(config,
{DOMAIN: [CONF_PUBLIC_KEY,
CONF_PRIVATE_KEY,
CONF_TOKEN,
CONF_TOKEN_SECRET]},
_LOGGER):
_LOGGER.error(
"Configuration Error: "
"Please make sure you have configured your keys "
"that can be aquired from https://api.telldus.com/keys/index")
return False
global NETWORK
NETWORK = TelldusLiveData(hass, config)
if not NETWORK.validate_session():
_LOGGER.error(
"Authentication Error: "
"Please make sure you have configured your keys "
"that can be aquired from https://api.telldus.com/keys/index")
return False
NETWORK.update(hass, config)
return True