core/homeassistant/components/tado/__init__.py

147 lines
4.1 KiB
Python

"""Support for the (unofficial) Tado API."""
import logging
import urllib
from datetime import timedelta
import voluptuous as vol
from homeassistant.helpers.discovery import load_platform
from homeassistant.helpers import config_validation as cv
from homeassistant.const import CONF_USERNAME, CONF_PASSWORD
from homeassistant.util import Throttle
_LOGGER = logging.getLogger(__name__)
DATA_TADO = "tado_data"
DOMAIN = "tado"
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=10)
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):
"""Set up of the Tado component."""
username = config[DOMAIN][CONF_USERNAME]
password = config[DOMAIN][CONF_PASSWORD]
from PyTado.interface import Tado
try:
tado = Tado(username, password)
tado.setDebugging(True)
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:
"""An object to store the Tado data."""
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:
if "zone" in sensor:
_LOGGER.debug(
"Querying mytado.com for zone %s %s",
sensor["id"],
sensor["name"],
)
data = self.tado.getState(sensor["id"])
if "device" in sensor:
_LOGGER.debug(
"Querying mytado.com for device %s %s",
sensor["id"],
sensor["name"],
)
data = self.tado.getDevices()[0]
except RuntimeError:
_LOGGER.error(
"Unable to connect to myTado. %s %s", sensor["id"], sensor["id"]
)
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."""
data = {"error": "no data"}
if data_id in self.data:
data = self.data[data_id]
return data
def get_zones(self):
"""Wrap for getZones()."""
return self.tado.getZones()
def get_capabilities(self, tado_id):
"""Wrap for getCapabilities(..)."""
return self.tado.getCapabilities(tado_id)
def get_me(self):
"""Wrap for getMet()."""
return self.tado.getMe()
def reset_zone_overlay(self, zone_id):
"""Wrap for resetZoneOverlay(..)."""
self.tado.resetZoneOverlay(zone_id)
self.update(no_throttle=True) # pylint: disable=unexpected-keyword-arg
def set_zone_overlay(
self,
zone_id,
overlay_mode,
temperature=None,
duration=None,
device_type="HEATING",
mode=None,
):
"""Wrap for setZoneOverlay(..)."""
self.tado.setZoneOverlay(
zone_id, overlay_mode, temperature, duration, device_type, "ON", mode
)
self.update(no_throttle=True) # pylint: disable=unexpected-keyword-arg
def set_zone_off(self, zone_id, overlay_mode, device_type="HEATING"):
"""Set a zone to off."""
self.tado.setZoneOverlay(zone_id, overlay_mode, None, None, device_type, "OFF")
self.update(no_throttle=True) # pylint: disable=unexpected-keyword-arg