2017-03-22 12:18:13 +00:00
|
|
|
"""
|
2017-03-26 13:50:40 +00:00
|
|
|
Support for the (unofficial) Tado api.
|
2017-03-22 12:18:13 +00:00
|
|
|
|
|
|
|
For more details about this component, please refer to the documentation at
|
|
|
|
https://home-assistant.io/components/tado/
|
|
|
|
"""
|
|
|
|
import logging
|
|
|
|
import urllib
|
|
|
|
from datetime import timedelta
|
2017-03-26 13:50:40 +00:00
|
|
|
|
2017-03-22 12:18:13 +00:00
|
|
|
import voluptuous as vol
|
|
|
|
|
|
|
|
from homeassistant.helpers.discovery import load_platform
|
|
|
|
from homeassistant.helpers import config_validation as cv
|
2017-03-26 13:50:40 +00:00
|
|
|
from homeassistant.const import CONF_USERNAME, CONF_PASSWORD
|
2017-03-22 12:18:13 +00:00
|
|
|
from homeassistant.util import Throttle
|
|
|
|
|
2017-03-26 13:50:40 +00:00
|
|
|
REQUIREMENTS = ['https://github.com/wmalgadey/PyTado/archive/'
|
|
|
|
'0.1.10.zip#'
|
|
|
|
'PyTado==0.1.10']
|
2017-03-22 12:18:13 +00:00
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
2017-03-26 13:50:40 +00:00
|
|
|
DATA_TADO = 'tado_data'
|
2017-03-22 12:18:13 +00:00
|
|
|
DOMAIN = 'tado'
|
|
|
|
|
2017-03-26 13:50:40 +00:00
|
|
|
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=10)
|
2017-03-22 12:18:13 +00:00
|
|
|
|
|
|
|
TADO_COMPONENTS = [
|
|
|
|
'sensor', 'climate'
|
|
|
|
]
|
|
|
|
|
|
|
|
CONFIG_SCHEMA = vol.Schema({
|
|
|
|
DOMAIN: vol.Schema({
|
|
|
|
vol.Required(CONF_USERNAME): cv.string,
|
|
|
|
vol.Required(CONF_PASSWORD): cv.string
|
|
|
|
})
|
|
|
|
}, extra=vol.ALLOW_EXTRA)
|
|
|
|
|
|
|
|
|
|
|
|
def setup(hass, config):
|
2017-03-26 13:50:40 +00:00
|
|
|
"""Set up of the Tado component."""
|
2017-03-22 12:18:13 +00:00
|
|
|
username = config[DOMAIN][CONF_USERNAME]
|
|
|
|
password = config[DOMAIN][CONF_PASSWORD]
|
|
|
|
|
|
|
|
from PyTado.interface import Tado
|
|
|
|
|
|
|
|
try:
|
|
|
|
tado = Tado(username, password)
|
|
|
|
except (RuntimeError, urllib.error.HTTPError):
|
|
|
|
_LOGGER.error("Unable to connect to mytado with username and password")
|
|
|
|
return False
|
|
|
|
|
|
|
|
hass.data[DATA_TADO] = TadoDataStore(tado)
|
|
|
|
|
|
|
|
for component in TADO_COMPONENTS:
|
|
|
|
load_platform(hass, component, DOMAIN, {}, config)
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
class TadoDataStore:
|
2017-03-26 13:50:40 +00:00
|
|
|
"""An object to store the Tado data."""
|
2017-03-22 12:18:13 +00:00
|
|
|
|
|
|
|
def __init__(self, tado):
|
|
|
|
"""Initialize Tado data store."""
|
|
|
|
self.tado = tado
|
|
|
|
|
|
|
|
self.sensors = {}
|
|
|
|
self.data = {}
|
|
|
|
|
|
|
|
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
|
|
|
def update(self):
|
|
|
|
"""Update the internal data from mytado.com."""
|
|
|
|
for data_id, sensor in list(self.sensors.items()):
|
|
|
|
data = None
|
|
|
|
|
|
|
|
try:
|
2017-03-26 13:50:40 +00:00
|
|
|
if 'zone' in sensor:
|
|
|
|
_LOGGER.info("Querying mytado.com for zone %s %s",
|
|
|
|
sensor['id'], sensor['name'])
|
|
|
|
data = self.tado.getState(sensor['id'])
|
|
|
|
|
|
|
|
if 'device' in sensor:
|
|
|
|
_LOGGER.info("Querying mytado.com for device %s %s",
|
|
|
|
sensor['id'], sensor['name'])
|
2017-03-22 12:18:13 +00:00
|
|
|
data = self.tado.getDevices()[0]
|
|
|
|
|
|
|
|
except RuntimeError:
|
|
|
|
_LOGGER.error("Unable to connect to myTado. %s %s",
|
2017-03-26 13:50:40 +00:00
|
|
|
sensor['id'], sensor['id'])
|
2017-03-22 12:18:13 +00:00
|
|
|
|
|
|
|
self.data[data_id] = data
|
|
|
|
|
|
|
|
def add_sensor(self, data_id, sensor):
|
|
|
|
"""Add a sensor to update in _update()."""
|
|
|
|
self.sensors[data_id] = sensor
|
|
|
|
self.data[data_id] = None
|
|
|
|
|
|
|
|
def get_data(self, data_id):
|
|
|
|
"""Get the cached data."""
|
2017-03-26 13:50:40 +00:00
|
|
|
data = {'error': 'no data'}
|
2017-03-22 12:18:13 +00:00
|
|
|
|
|
|
|
if data_id in self.data:
|
|
|
|
data = self.data[data_id]
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
def get_zones(self):
|
|
|
|
"""Wrapper for getZones()."""
|
|
|
|
return self.tado.getZones()
|
|
|
|
|
|
|
|
def get_capabilities(self, tado_id):
|
|
|
|
"""Wrapper for getCapabilities(..)."""
|
|
|
|
return self.tado.getCapabilities(tado_id)
|
|
|
|
|
|
|
|
def get_me(self):
|
|
|
|
"""Wrapper for getMet()."""
|
|
|
|
return self.tado.getMe()
|
|
|
|
|
|
|
|
def reset_zone_overlay(self, zone_id):
|
|
|
|
"""Wrapper for resetZoneOverlay(..)."""
|
|
|
|
return self.tado.resetZoneOverlay(zone_id)
|
|
|
|
|
2017-04-02 16:47:15 +00:00
|
|
|
def set_zone_overlay(self, zone_id, mode, temperature=None, duration=None):
|
2017-03-22 12:18:13 +00:00
|
|
|
"""Wrapper for setZoneOverlay(..)."""
|
2017-04-02 16:47:15 +00:00
|
|
|
return self.tado.setZoneOverlay(zone_id, mode, temperature, duration)
|