This reverts commit c2b03332a0
.
This commit is contained in:
parent
ac9c9377c2
commit
8c52e2c923
25 changed files with 410 additions and 1999 deletions
|
@ -350,7 +350,7 @@ homeassistant/components/switchmate/* @danielhiversen
|
|||
homeassistant/components/syncthru/* @nielstron
|
||||
homeassistant/components/synology_srm/* @aerialls
|
||||
homeassistant/components/syslog/* @fabaff
|
||||
homeassistant/components/tado/* @michaelarnauts @bdraco
|
||||
homeassistant/components/tado/* @michaelarnauts
|
||||
homeassistant/components/tahoma/* @philklei
|
||||
homeassistant/components/tankerkoenig/* @guillempages
|
||||
homeassistant/components/tautulli/* @ludeeus
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
"""Support for the (unofficial) Tado API."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
import urllib
|
||||
|
||||
from PyTado.interface import Tado
|
||||
from requests import RequestException
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.discovery import load_platform
|
||||
from homeassistant.helpers.dispatcher import dispatcher_send
|
||||
|
@ -110,7 +109,7 @@ class TadoConnector:
|
|||
"""Connect to Tado and fetch the zones."""
|
||||
try:
|
||||
self.tado = Tado(self._username, self._password)
|
||||
except (RuntimeError, RequestException) as exc:
|
||||
except (RuntimeError, urllib.error.HTTPError) as exc:
|
||||
_LOGGER.error("Unable to connect: %s", exc)
|
||||
return False
|
||||
|
||||
|
@ -137,12 +136,7 @@ class TadoConnector:
|
|||
if sensor_type == "zone":
|
||||
data = self.tado.getState(sensor)
|
||||
elif sensor_type == "device":
|
||||
devices_data = self.tado.getDevices()
|
||||
if not devices_data:
|
||||
_LOGGER.info("There are no devices to setup on this tado account.")
|
||||
return
|
||||
|
||||
data = devices_data[0]
|
||||
data = self.tado.getDevices()[0]
|
||||
else:
|
||||
_LOGGER.debug("Unknown sensor: %s", sensor_type)
|
||||
return
|
||||
|
@ -168,62 +162,31 @@ class TadoConnector:
|
|||
self.tado.resetZoneOverlay(zone_id)
|
||||
self.update_sensor("zone", zone_id)
|
||||
|
||||
def set_home(self):
|
||||
"""Put tado in home mode."""
|
||||
response_json = None
|
||||
try:
|
||||
response_json = self.tado.setHome()
|
||||
except RequestException as exc:
|
||||
_LOGGER.error("Could not set home: %s", exc)
|
||||
|
||||
_raise_home_away_errors(response_json)
|
||||
|
||||
def set_away(self):
|
||||
"""Put tado in away mode."""
|
||||
response_json = None
|
||||
try:
|
||||
response_json = self.tado.setAway()
|
||||
except RequestException as exc:
|
||||
_LOGGER.error("Could not set away: %s", exc)
|
||||
|
||||
_raise_home_away_errors(response_json)
|
||||
|
||||
def set_zone_overlay(
|
||||
self,
|
||||
zone_id=None,
|
||||
overlay_mode=None,
|
||||
zone_id,
|
||||
overlay_mode,
|
||||
temperature=None,
|
||||
duration=None,
|
||||
device_type="HEATING",
|
||||
mode=None,
|
||||
fan_speed=None,
|
||||
):
|
||||
"""Set a zone overlay."""
|
||||
_LOGGER.debug(
|
||||
"Set overlay for zone %s: overlay_mode=%s, temp=%s, duration=%s, type=%s, mode=%s fan_speed=%s",
|
||||
"Set overlay for zone %s: mode=%s, temp=%s, duration=%s, type=%s, mode=%s",
|
||||
zone_id,
|
||||
overlay_mode,
|
||||
temperature,
|
||||
duration,
|
||||
device_type,
|
||||
mode,
|
||||
fan_speed,
|
||||
)
|
||||
|
||||
try:
|
||||
self.tado.setZoneOverlay(
|
||||
zone_id,
|
||||
overlay_mode,
|
||||
temperature,
|
||||
duration,
|
||||
device_type,
|
||||
"ON",
|
||||
mode,
|
||||
fan_speed,
|
||||
zone_id, overlay_mode, temperature, duration, device_type, "ON", mode
|
||||
)
|
||||
|
||||
except RequestException as exc:
|
||||
_LOGGER.error("Could not set zone overlay: %s", exc)
|
||||
except urllib.error.HTTPError as exc:
|
||||
_LOGGER.error("Could not set zone overlay: %s", exc.read())
|
||||
|
||||
self.update_sensor("zone", zone_id)
|
||||
|
||||
|
@ -233,18 +196,7 @@ class TadoConnector:
|
|||
self.tado.setZoneOverlay(
|
||||
zone_id, overlay_mode, None, None, device_type, "OFF"
|
||||
)
|
||||
except RequestException as exc:
|
||||
_LOGGER.error("Could not set zone overlay: %s", exc)
|
||||
except urllib.error.HTTPError as exc:
|
||||
_LOGGER.error("Could not set zone overlay: %s", exc.read())
|
||||
|
||||
self.update_sensor("zone", zone_id)
|
||||
|
||||
|
||||
def _raise_home_away_errors(response_json):
|
||||
if response_json is None:
|
||||
return
|
||||
|
||||
# Likely we are displaying to the user:
|
||||
# Tried to update to HOME though all mobile devices are detected outside the home fence
|
||||
if "errors" in response_json and len(response_json["errors"]) > 0:
|
||||
error_list = response_json["errors"]
|
||||
raise HomeAssistantError(error_list[0]["title"])
|
||||
|
|
|
@ -3,12 +3,21 @@ import logging
|
|||
|
||||
from homeassistant.components.climate import ClimateDevice
|
||||
from homeassistant.components.climate.const import (
|
||||
CURRENT_HVAC_COOL,
|
||||
CURRENT_HVAC_HEAT,
|
||||
CURRENT_HVAC_IDLE,
|
||||
CURRENT_HVAC_OFF,
|
||||
FAN_AUTO,
|
||||
FAN_HIGH,
|
||||
FAN_LOW,
|
||||
FAN_MIDDLE,
|
||||
FAN_OFF,
|
||||
HVAC_MODE_AUTO,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_HEAT_COOL,
|
||||
HVAC_MODE_OFF,
|
||||
PRESET_AWAY,
|
||||
PRESET_HOME,
|
||||
SUPPORT_FAN_MODE,
|
||||
SUPPORT_PRESET_MODE,
|
||||
SUPPORT_TARGET_TEMPERATURE,
|
||||
)
|
||||
|
@ -18,29 +27,49 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|||
|
||||
from . import DOMAIN, SIGNAL_TADO_UPDATE_RECEIVED
|
||||
from .const import (
|
||||
CONST_FAN_AUTO,
|
||||
CONST_FAN_OFF,
|
||||
CONST_MODE_COOL,
|
||||
CONST_MODE_HEAT,
|
||||
CONST_MODE_OFF,
|
||||
CONST_MODE_SMART_SCHEDULE,
|
||||
CONST_OVERLAY_MANUAL,
|
||||
CONST_OVERLAY_TADO_MODE,
|
||||
CONST_OVERLAY_TIMER,
|
||||
DATA,
|
||||
HA_TO_TADO_FAN_MODE_MAP,
|
||||
HA_TO_TADO_HVAC_MODE_MAP,
|
||||
ORDERED_KNOWN_TADO_MODES,
|
||||
SUPPORT_PRESET,
|
||||
TADO_MODES_WITH_NO_TEMP_SETTING,
|
||||
TADO_TO_HA_FAN_MODE_MAP,
|
||||
TADO_TO_HA_HVAC_MODE_MAP,
|
||||
TYPE_AIR_CONDITIONING,
|
||||
TYPE_HEATING,
|
||||
)
|
||||
from .tado_adapter import TadoZoneData
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
FAN_MAP_TADO = {"HIGH": FAN_HIGH, "MIDDLE": FAN_MIDDLE, "LOW": FAN_LOW}
|
||||
|
||||
HVAC_MAP_TADO_HEAT = {
|
||||
CONST_OVERLAY_MANUAL: HVAC_MODE_HEAT,
|
||||
CONST_OVERLAY_TIMER: HVAC_MODE_HEAT,
|
||||
CONST_OVERLAY_TADO_MODE: HVAC_MODE_HEAT,
|
||||
CONST_MODE_SMART_SCHEDULE: HVAC_MODE_AUTO,
|
||||
CONST_MODE_OFF: HVAC_MODE_OFF,
|
||||
}
|
||||
HVAC_MAP_TADO_COOL = {
|
||||
CONST_OVERLAY_MANUAL: HVAC_MODE_COOL,
|
||||
CONST_OVERLAY_TIMER: HVAC_MODE_COOL,
|
||||
CONST_OVERLAY_TADO_MODE: HVAC_MODE_COOL,
|
||||
CONST_MODE_SMART_SCHEDULE: HVAC_MODE_AUTO,
|
||||
CONST_MODE_OFF: HVAC_MODE_OFF,
|
||||
}
|
||||
HVAC_MAP_TADO_HEAT_COOL = {
|
||||
CONST_OVERLAY_MANUAL: HVAC_MODE_HEAT_COOL,
|
||||
CONST_OVERLAY_TIMER: HVAC_MODE_HEAT_COOL,
|
||||
CONST_OVERLAY_TADO_MODE: HVAC_MODE_HEAT_COOL,
|
||||
CONST_MODE_SMART_SCHEDULE: HVAC_MODE_AUTO,
|
||||
CONST_MODE_OFF: HVAC_MODE_OFF,
|
||||
}
|
||||
|
||||
SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE
|
||||
SUPPORT_HVAC_HEAT = [HVAC_MODE_HEAT, HVAC_MODE_AUTO, HVAC_MODE_OFF]
|
||||
SUPPORT_HVAC_COOL = [HVAC_MODE_COOL, HVAC_MODE_AUTO, HVAC_MODE_OFF]
|
||||
SUPPORT_HVAC_HEAT_COOL = [HVAC_MODE_HEAT_COOL, HVAC_MODE_AUTO, HVAC_MODE_OFF]
|
||||
SUPPORT_FAN = [FAN_HIGH, FAN_MIDDLE, FAN_LOW, FAN_OFF]
|
||||
SUPPORT_PRESET = [PRESET_AWAY, PRESET_HOME]
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the Tado climate platform."""
|
||||
|
@ -67,80 +96,29 @@ def create_climate_entity(tado, name: str, zone_id: int):
|
|||
_LOGGER.debug("Capabilities for zone %s: %s", zone_id, capabilities)
|
||||
|
||||
zone_type = capabilities["type"]
|
||||
support_flags = SUPPORT_PRESET_MODE | SUPPORT_TARGET_TEMPERATURE
|
||||
supported_hvac_modes = [
|
||||
TADO_TO_HA_HVAC_MODE_MAP[CONST_MODE_OFF],
|
||||
TADO_TO_HA_HVAC_MODE_MAP[CONST_MODE_SMART_SCHEDULE],
|
||||
]
|
||||
supported_fan_modes = None
|
||||
heat_temperatures = None
|
||||
cool_temperatures = None
|
||||
|
||||
ac_support_heat = False
|
||||
if zone_type == TYPE_AIR_CONDITIONING:
|
||||
# Only use heat if available
|
||||
# (you don't have to setup a heat mode, but cool is required)
|
||||
# Heat is preferred as it generally has a lower minimum temperature
|
||||
for mode in ORDERED_KNOWN_TADO_MODES:
|
||||
if mode not in capabilities:
|
||||
continue
|
||||
|
||||
supported_hvac_modes.append(TADO_TO_HA_HVAC_MODE_MAP[mode])
|
||||
if not capabilities[mode].get("fanSpeeds"):
|
||||
continue
|
||||
|
||||
support_flags |= SUPPORT_FAN_MODE
|
||||
|
||||
if supported_fan_modes:
|
||||
continue
|
||||
|
||||
supported_fan_modes = [
|
||||
TADO_TO_HA_FAN_MODE_MAP[speed]
|
||||
for speed in capabilities[mode]["fanSpeeds"]
|
||||
]
|
||||
|
||||
cool_temperatures = capabilities[CONST_MODE_COOL]["temperatures"]
|
||||
if "HEAT" in capabilities:
|
||||
temperatures = capabilities["HEAT"]["temperatures"]
|
||||
ac_support_heat = True
|
||||
else:
|
||||
temperatures = capabilities["COOL"]["temperatures"]
|
||||
elif "temperatures" in capabilities:
|
||||
temperatures = capabilities["temperatures"]
|
||||
else:
|
||||
supported_hvac_modes.append(HVAC_MODE_HEAT)
|
||||
|
||||
if CONST_MODE_HEAT in capabilities:
|
||||
heat_temperatures = capabilities[CONST_MODE_HEAT]["temperatures"]
|
||||
|
||||
if heat_temperatures is None and "temperatures" in capabilities:
|
||||
heat_temperatures = capabilities["temperatures"]
|
||||
|
||||
if cool_temperatures is None and heat_temperatures is None:
|
||||
_LOGGER.debug("Not adding zone %s since it has no temperatures", name)
|
||||
_LOGGER.debug("Not adding zone %s since it has no temperature", name)
|
||||
return None
|
||||
|
||||
heat_min_temp = None
|
||||
heat_max_temp = None
|
||||
heat_step = None
|
||||
cool_min_temp = None
|
||||
cool_max_temp = None
|
||||
cool_step = None
|
||||
|
||||
if heat_temperatures is not None:
|
||||
heat_min_temp = float(heat_temperatures["celsius"]["min"])
|
||||
heat_max_temp = float(heat_temperatures["celsius"]["max"])
|
||||
heat_step = heat_temperatures["celsius"].get("step", PRECISION_TENTHS)
|
||||
|
||||
if cool_temperatures is not None:
|
||||
cool_min_temp = float(cool_temperatures["celsius"]["min"])
|
||||
cool_max_temp = float(cool_temperatures["celsius"]["max"])
|
||||
cool_step = cool_temperatures["celsius"].get("step", PRECISION_TENTHS)
|
||||
min_temp = float(temperatures["celsius"]["min"])
|
||||
max_temp = float(temperatures["celsius"]["max"])
|
||||
step = temperatures["celsius"].get("step", PRECISION_TENTHS)
|
||||
|
||||
entity = TadoClimate(
|
||||
tado,
|
||||
name,
|
||||
zone_id,
|
||||
zone_type,
|
||||
heat_min_temp,
|
||||
heat_max_temp,
|
||||
heat_step,
|
||||
cool_min_temp,
|
||||
cool_max_temp,
|
||||
cool_step,
|
||||
supported_hvac_modes,
|
||||
supported_fan_modes,
|
||||
support_flags,
|
||||
tado, name, zone_id, zone_type, min_temp, max_temp, step, ac_support_heat,
|
||||
)
|
||||
return entity
|
||||
|
||||
|
@ -154,15 +132,10 @@ class TadoClimate(ClimateDevice):
|
|||
zone_name,
|
||||
zone_id,
|
||||
zone_type,
|
||||
heat_min_temp,
|
||||
heat_max_temp,
|
||||
heat_step,
|
||||
cool_min_temp,
|
||||
cool_max_temp,
|
||||
cool_step,
|
||||
supported_hvac_modes,
|
||||
supported_fan_modes,
|
||||
support_flags,
|
||||
min_temp,
|
||||
max_temp,
|
||||
step,
|
||||
ac_support_heat,
|
||||
):
|
||||
"""Initialize of Tado climate entity."""
|
||||
self._tado = tado
|
||||
|
@ -173,45 +146,49 @@ class TadoClimate(ClimateDevice):
|
|||
self._unique_id = f"{zone_type} {zone_id} {tado.device_id}"
|
||||
|
||||
self._ac_device = zone_type == TYPE_AIR_CONDITIONING
|
||||
self._supported_hvac_modes = supported_hvac_modes
|
||||
self._supported_fan_modes = supported_fan_modes
|
||||
self._support_flags = support_flags
|
||||
self._ac_support_heat = ac_support_heat
|
||||
self._cooling = False
|
||||
|
||||
self._available = False
|
||||
self._active = False
|
||||
self._device_is_active = False
|
||||
|
||||
self._cur_temp = None
|
||||
self._cur_humidity = None
|
||||
|
||||
self._heat_min_temp = heat_min_temp
|
||||
self._heat_max_temp = heat_max_temp
|
||||
self._heat_step = heat_step
|
||||
|
||||
self._cool_min_temp = cool_min_temp
|
||||
self._cool_max_temp = cool_max_temp
|
||||
self._cool_step = cool_step
|
||||
|
||||
self._is_away = False
|
||||
self._min_temp = min_temp
|
||||
self._max_temp = max_temp
|
||||
self._step = step
|
||||
self._target_temp = None
|
||||
|
||||
self._current_tado_fan_speed = CONST_FAN_OFF
|
||||
self._current_tado_hvac_mode = CONST_MODE_OFF
|
||||
self._current_hvac_action = CURRENT_HVAC_OFF
|
||||
if tado.fallback:
|
||||
# Fallback to Smart Schedule at next Schedule switch
|
||||
self._default_overlay = CONST_OVERLAY_TADO_MODE
|
||||
else:
|
||||
# Don't fallback to Smart Schedule, but keep in manual mode
|
||||
self._default_overlay = CONST_OVERLAY_MANUAL
|
||||
|
||||
self._tado_zone_data = None
|
||||
self._async_update_zone_data()
|
||||
self._current_fan = CONST_MODE_OFF
|
||||
self._current_operation = CONST_MODE_SMART_SCHEDULE
|
||||
self._overlay_mode = CONST_MODE_SMART_SCHEDULE
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Register for sensor updates."""
|
||||
|
||||
@callback
|
||||
def async_update_callback():
|
||||
"""Schedule an entity update."""
|
||||
self.async_schedule_update_ha_state(True)
|
||||
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
SIGNAL_TADO_UPDATE_RECEIVED.format("zone", self.zone_id),
|
||||
self._async_update_callback,
|
||||
async_update_callback,
|
||||
)
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Return the list of supported features."""
|
||||
return self._support_flags
|
||||
return SUPPORT_FLAGS
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -231,12 +208,12 @@ class TadoClimate(ClimateDevice):
|
|||
@property
|
||||
def current_humidity(self):
|
||||
"""Return the current humidity."""
|
||||
return self._tado_zone_data.current_humidity
|
||||
return self._cur_humidity
|
||||
|
||||
@property
|
||||
def current_temperature(self):
|
||||
"""Return the sensor temperature."""
|
||||
return self._tado_zone_data.current_temp
|
||||
return self._cur_temp
|
||||
|
||||
@property
|
||||
def hvac_mode(self):
|
||||
|
@ -244,9 +221,11 @@ class TadoClimate(ClimateDevice):
|
|||
|
||||
Need to be one of HVAC_MODE_*.
|
||||
"""
|
||||
return TADO_TO_HA_HVAC_MODE_MAP.get(
|
||||
self._tado_zone_data.current_tado_hvac_mode, CURRENT_HVAC_OFF
|
||||
)
|
||||
if self._ac_device and self._ac_support_heat:
|
||||
return HVAC_MAP_TADO_HEAT_COOL.get(self._current_operation)
|
||||
if self._ac_device and not self._ac_support_heat:
|
||||
return HVAC_MAP_TADO_COOL.get(self._current_operation)
|
||||
return HVAC_MAP_TADO_HEAT.get(self._current_operation)
|
||||
|
||||
@property
|
||||
def hvac_modes(self):
|
||||
|
@ -254,7 +233,11 @@ class TadoClimate(ClimateDevice):
|
|||
|
||||
Need to be a subset of HVAC_MODES.
|
||||
"""
|
||||
return self._supported_hvac_modes
|
||||
if self._ac_device:
|
||||
if self._ac_support_heat:
|
||||
return SUPPORT_HVAC_HEAT_COOL
|
||||
return SUPPORT_HVAC_COOL
|
||||
return SUPPORT_HVAC_HEAT
|
||||
|
||||
@property
|
||||
def hvac_action(self):
|
||||
|
@ -262,28 +245,40 @@ class TadoClimate(ClimateDevice):
|
|||
|
||||
Need to be one of CURRENT_HVAC_*.
|
||||
"""
|
||||
return self._tado_zone_data.current_hvac_action
|
||||
if not self._device_is_active:
|
||||
return CURRENT_HVAC_OFF
|
||||
if self._ac_device:
|
||||
if self._active:
|
||||
if self._ac_support_heat and not self._cooling:
|
||||
return CURRENT_HVAC_HEAT
|
||||
return CURRENT_HVAC_COOL
|
||||
return CURRENT_HVAC_IDLE
|
||||
if self._active:
|
||||
return CURRENT_HVAC_HEAT
|
||||
return CURRENT_HVAC_IDLE
|
||||
|
||||
@property
|
||||
def fan_mode(self):
|
||||
"""Return the fan setting."""
|
||||
if self._ac_device:
|
||||
return TADO_TO_HA_FAN_MODE_MAP.get(self._current_tado_fan_speed, FAN_AUTO)
|
||||
return FAN_MAP_TADO.get(self._current_fan)
|
||||
return None
|
||||
|
||||
@property
|
||||
def fan_modes(self):
|
||||
"""List of available fan modes."""
|
||||
return self._supported_fan_modes
|
||||
if self._ac_device:
|
||||
return SUPPORT_FAN
|
||||
return None
|
||||
|
||||
def set_fan_mode(self, fan_mode: str):
|
||||
"""Turn fan on/off."""
|
||||
self._control_hvac(fan_mode=HA_TO_TADO_FAN_MODE_MAP[fan_mode])
|
||||
pass
|
||||
|
||||
@property
|
||||
def preset_mode(self):
|
||||
"""Return the current preset mode (home, away)."""
|
||||
if self._tado_zone_data.is_away:
|
||||
if self._is_away:
|
||||
return PRESET_AWAY
|
||||
return PRESET_HOME
|
||||
|
||||
|
@ -294,10 +289,7 @@ class TadoClimate(ClimateDevice):
|
|||
|
||||
def set_preset_mode(self, preset_mode):
|
||||
"""Set new preset mode."""
|
||||
if preset_mode == PRESET_HOME:
|
||||
self._tado.set_home()
|
||||
else:
|
||||
self._tado.set_away()
|
||||
pass
|
||||
|
||||
@property
|
||||
def temperature_unit(self):
|
||||
|
@ -307,14 +299,12 @@ class TadoClimate(ClimateDevice):
|
|||
@property
|
||||
def target_temperature_step(self):
|
||||
"""Return the supported step of target temperature."""
|
||||
if self._tado_zone_data.current_tado_hvac_mode == CONST_MODE_COOL:
|
||||
return self._cool_step or self._heat_step
|
||||
return self._heat_step or self._cool_step
|
||||
return self._step
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
"""Return the temperature we try to reach."""
|
||||
return self._tado_zone_data.target_temp
|
||||
return self._target_temp
|
||||
|
||||
def set_temperature(self, **kwargs):
|
||||
"""Set new target temperature."""
|
||||
|
@ -322,142 +312,174 @@ class TadoClimate(ClimateDevice):
|
|||
if temperature is None:
|
||||
return
|
||||
|
||||
self._control_hvac(target_temp=temperature)
|
||||
self._current_operation = self._default_overlay
|
||||
self._overlay_mode = None
|
||||
self._target_temp = temperature
|
||||
self._control_heating()
|
||||
|
||||
def set_hvac_mode(self, hvac_mode):
|
||||
"""Set new target hvac mode."""
|
||||
mode = None
|
||||
|
||||
self._control_hvac(hvac_mode=HA_TO_TADO_HVAC_MODE_MAP[hvac_mode])
|
||||
if hvac_mode == HVAC_MODE_OFF:
|
||||
mode = CONST_MODE_OFF
|
||||
elif hvac_mode == HVAC_MODE_AUTO:
|
||||
mode = CONST_MODE_SMART_SCHEDULE
|
||||
elif hvac_mode == HVAC_MODE_HEAT:
|
||||
mode = self._default_overlay
|
||||
elif hvac_mode == HVAC_MODE_COOL:
|
||||
mode = self._default_overlay
|
||||
elif hvac_mode == HVAC_MODE_HEAT_COOL:
|
||||
mode = self._default_overlay
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Return if the device is available."""
|
||||
return self._tado_zone_data.available
|
||||
self._current_operation = mode
|
||||
self._overlay_mode = None
|
||||
|
||||
# Set a target temperature if we don't have any
|
||||
# This can happen when we switch from Off to On
|
||||
if self._target_temp is None:
|
||||
if self._ac_device:
|
||||
self._target_temp = self.max_temp
|
||||
else:
|
||||
self._target_temp = self.min_temp
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
self._control_heating()
|
||||
|
||||
@property
|
||||
def min_temp(self):
|
||||
"""Return the minimum temperature."""
|
||||
if (
|
||||
self._current_tado_hvac_mode == CONST_MODE_COOL
|
||||
and self._cool_min_temp is not None
|
||||
):
|
||||
return self._cool_min_temp
|
||||
if self._heat_min_temp is not None:
|
||||
return self._heat_min_temp
|
||||
|
||||
return self._cool_min_temp
|
||||
return self._min_temp
|
||||
|
||||
@property
|
||||
def max_temp(self):
|
||||
"""Return the maximum temperature."""
|
||||
return self._max_temp
|
||||
|
||||
def update(self):
|
||||
"""Handle update callbacks."""
|
||||
_LOGGER.debug("Updating climate platform for zone %d", self.zone_id)
|
||||
data = self._tado.data["zone"][self.zone_id]
|
||||
|
||||
if "sensorDataPoints" in data:
|
||||
sensor_data = data["sensorDataPoints"]
|
||||
|
||||
if "insideTemperature" in sensor_data:
|
||||
temperature = float(sensor_data["insideTemperature"]["celsius"])
|
||||
self._cur_temp = temperature
|
||||
|
||||
if "humidity" in sensor_data:
|
||||
humidity = float(sensor_data["humidity"]["percentage"])
|
||||
self._cur_humidity = humidity
|
||||
|
||||
# temperature setting will not exist when device is off
|
||||
if (
|
||||
self._current_tado_hvac_mode == CONST_MODE_HEAT
|
||||
and self._heat_max_temp is not None
|
||||
"temperature" in data["setting"]
|
||||
and data["setting"]["temperature"] is not None
|
||||
):
|
||||
return self._heat_max_temp
|
||||
if self._heat_max_temp is not None:
|
||||
return self._heat_max_temp
|
||||
setting = float(data["setting"]["temperature"]["celsius"])
|
||||
self._target_temp = setting
|
||||
|
||||
return self._heat_max_temp
|
||||
if "tadoMode" in data:
|
||||
mode = data["tadoMode"]
|
||||
self._is_away = mode == "AWAY"
|
||||
|
||||
@callback
|
||||
def _async_update_zone_data(self):
|
||||
"""Load tado data into zone."""
|
||||
self._tado_zone_data = TadoZoneData(
|
||||
self._tado.data["zone"][self.zone_id], self.zone_id
|
||||
)
|
||||
|
||||
@callback
|
||||
def _async_update_callback(self):
|
||||
"""Load tado data and update state."""
|
||||
self._async_update_zone_data()
|
||||
self.async_write_ha_state()
|
||||
|
||||
def _normalize_target_temp_for_hvac_mode(self):
|
||||
# Set a target temperature if we don't have any
|
||||
# This can happen when we switch from Off to On
|
||||
if self._target_temp is None:
|
||||
if self._current_tado_hvac_mode == CONST_MODE_COOL:
|
||||
self._target_temp = self._cool_max_temp
|
||||
if "setting" in data:
|
||||
power = data["setting"]["power"]
|
||||
if power == "OFF":
|
||||
self._current_operation = CONST_MODE_OFF
|
||||
self._current_fan = CONST_MODE_OFF
|
||||
# There is no overlay, the mode will always be
|
||||
# "SMART_SCHEDULE"
|
||||
self._overlay_mode = CONST_MODE_SMART_SCHEDULE
|
||||
self._device_is_active = False
|
||||
else:
|
||||
self._target_temp = self._heat_min_temp
|
||||
elif self._current_tado_hvac_mode == CONST_MODE_COOL:
|
||||
if self._target_temp > self._cool_max_temp:
|
||||
self._target_temp = self._cool_max_temp
|
||||
elif self._target_temp < self._cool_min_temp:
|
||||
self._target_temp = self._cool_min_temp
|
||||
elif self._current_tado_hvac_mode == CONST_MODE_HEAT:
|
||||
if self._target_temp > self._heat_max_temp:
|
||||
self._target_temp = self._heat_max_temp
|
||||
elif self._target_temp < self._heat_min_temp:
|
||||
self._target_temp = self._heat_min_temp
|
||||
self._device_is_active = True
|
||||
|
||||
def _control_hvac(self, hvac_mode=None, target_temp=None, fan_mode=None):
|
||||
active = False
|
||||
if "activityDataPoints" in data:
|
||||
activity_data = data["activityDataPoints"]
|
||||
if self._ac_device:
|
||||
if "acPower" in activity_data and activity_data["acPower"] is not None:
|
||||
if not activity_data["acPower"]["value"] == "OFF":
|
||||
active = True
|
||||
else:
|
||||
if (
|
||||
"heatingPower" in activity_data
|
||||
and activity_data["heatingPower"] is not None
|
||||
):
|
||||
if float(activity_data["heatingPower"]["percentage"]) > 0.0:
|
||||
active = True
|
||||
self._active = active
|
||||
|
||||
overlay = False
|
||||
overlay_data = None
|
||||
termination = CONST_MODE_SMART_SCHEDULE
|
||||
cooling = False
|
||||
fan_speed = CONST_MODE_OFF
|
||||
|
||||
if "overlay" in data:
|
||||
overlay_data = data["overlay"]
|
||||
overlay = overlay_data is not None
|
||||
|
||||
if overlay:
|
||||
termination = overlay_data["termination"]["type"]
|
||||
setting = False
|
||||
setting_data = None
|
||||
|
||||
if "setting" in overlay_data:
|
||||
setting_data = overlay_data["setting"]
|
||||
setting = setting_data is not None
|
||||
|
||||
if setting:
|
||||
if "mode" in setting_data:
|
||||
cooling = setting_data["mode"] == "COOL"
|
||||
|
||||
if "fanSpeed" in setting_data:
|
||||
fan_speed = setting_data["fanSpeed"]
|
||||
|
||||
if self._device_is_active:
|
||||
# If you set mode manually to off, there will be an overlay
|
||||
# and a termination, but we want to see the mode "OFF"
|
||||
self._overlay_mode = termination
|
||||
self._current_operation = termination
|
||||
|
||||
self._cooling = cooling
|
||||
self._current_fan = fan_speed
|
||||
|
||||
def _control_heating(self):
|
||||
"""Send new target temperature to Tado."""
|
||||
|
||||
if hvac_mode:
|
||||
self._current_tado_hvac_mode = hvac_mode
|
||||
|
||||
if target_temp:
|
||||
self._target_temp = target_temp
|
||||
|
||||
if fan_mode:
|
||||
self._current_tado_fan_speed = fan_mode
|
||||
|
||||
self._normalize_target_temp_for_hvac_mode()
|
||||
|
||||
# tado does not permit setting the fan speed to
|
||||
# off, you must turn off the device
|
||||
if (
|
||||
self._current_tado_fan_speed == CONST_FAN_OFF
|
||||
and self._current_tado_hvac_mode != CONST_MODE_OFF
|
||||
):
|
||||
self._current_tado_fan_speed = CONST_FAN_AUTO
|
||||
|
||||
if self._current_tado_hvac_mode == CONST_MODE_OFF:
|
||||
_LOGGER.debug(
|
||||
"Switching to OFF for zone %s (%d)", self.zone_name, self.zone_id
|
||||
)
|
||||
self._tado.set_zone_off(self.zone_id, CONST_OVERLAY_MANUAL, self.zone_type)
|
||||
return
|
||||
|
||||
if self._current_tado_hvac_mode == CONST_MODE_SMART_SCHEDULE:
|
||||
if self._current_operation == CONST_MODE_SMART_SCHEDULE:
|
||||
_LOGGER.debug(
|
||||
"Switching to SMART_SCHEDULE for zone %s (%d)",
|
||||
self.zone_name,
|
||||
self.zone_id,
|
||||
)
|
||||
self._tado.reset_zone_overlay(self.zone_id)
|
||||
self._overlay_mode = self._current_operation
|
||||
return
|
||||
|
||||
if self._current_operation == CONST_MODE_OFF:
|
||||
_LOGGER.debug(
|
||||
"Switching to OFF for zone %s (%d)", self.zone_name, self.zone_id
|
||||
)
|
||||
self._tado.set_zone_off(self.zone_id, CONST_OVERLAY_MANUAL, self.zone_type)
|
||||
self._overlay_mode = self._current_operation
|
||||
return
|
||||
|
||||
_LOGGER.debug(
|
||||
"Switching to %s for zone %s (%d) with temperature %s °C",
|
||||
self._current_tado_hvac_mode,
|
||||
self._current_operation,
|
||||
self.zone_name,
|
||||
self.zone_id,
|
||||
self._target_temp,
|
||||
)
|
||||
|
||||
# Fallback to Smart Schedule at next Schedule switch if we have fallback enabled
|
||||
overlay_mode = (
|
||||
CONST_OVERLAY_TADO_MODE if self._tado.fallback else CONST_OVERLAY_MANUAL
|
||||
)
|
||||
|
||||
temperature_to_send = self._target_temp
|
||||
if self._current_tado_hvac_mode in TADO_MODES_WITH_NO_TEMP_SETTING:
|
||||
# A temperature cannot be passed with these modes
|
||||
temperature_to_send = None
|
||||
|
||||
self._tado.set_zone_overlay(
|
||||
zone_id=self.zone_id,
|
||||
overlay_mode=overlay_mode, # What to do when the period ends
|
||||
temperature=temperature_to_send,
|
||||
duration=None,
|
||||
device_type=self.zone_type,
|
||||
mode=self._current_tado_hvac_mode,
|
||||
fan_speed=(
|
||||
self._current_tado_fan_speed
|
||||
if (self._support_flags & SUPPORT_FAN_MODE)
|
||||
else None
|
||||
), # api defaults to not sending fanSpeed if not specified
|
||||
self.zone_id,
|
||||
self._current_operation,
|
||||
self._target_temp,
|
||||
None,
|
||||
self.zone_type,
|
||||
"COOL" if self._ac_device else None,
|
||||
)
|
||||
self._overlay_mode = self._current_operation
|
||||
|
|
|
@ -1,26 +1,5 @@
|
|||
"""Constant values for the Tado component."""
|
||||
|
||||
from homeassistant.components.climate.const import (
|
||||
CURRENT_HVAC_COOL,
|
||||
CURRENT_HVAC_DRY,
|
||||
CURRENT_HVAC_FAN,
|
||||
CURRENT_HVAC_HEAT,
|
||||
FAN_AUTO,
|
||||
FAN_HIGH,
|
||||
FAN_LOW,
|
||||
FAN_MEDIUM,
|
||||
FAN_OFF,
|
||||
HVAC_MODE_AUTO,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_DRY,
|
||||
HVAC_MODE_FAN_ONLY,
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_HEAT_COOL,
|
||||
HVAC_MODE_OFF,
|
||||
PRESET_AWAY,
|
||||
PRESET_HOME,
|
||||
)
|
||||
|
||||
# Configuration
|
||||
CONF_FALLBACK = "fallback"
|
||||
DATA = "data"
|
||||
|
@ -31,81 +10,10 @@ TYPE_HEATING = "HEATING"
|
|||
TYPE_HOT_WATER = "HOT_WATER"
|
||||
|
||||
# Base modes
|
||||
CONST_MODE_OFF = "OFF"
|
||||
CONST_MODE_SMART_SCHEDULE = "SMART_SCHEDULE" # Use the schedule
|
||||
CONST_MODE_AUTO = "AUTO"
|
||||
CONST_MODE_COOL = "COOL"
|
||||
CONST_MODE_HEAT = "HEAT"
|
||||
CONST_MODE_DRY = "DRY"
|
||||
CONST_MODE_FAN = "FAN"
|
||||
|
||||
CONST_LINK_OFFLINE = "OFFLINE"
|
||||
|
||||
CONST_FAN_OFF = "OFF"
|
||||
CONST_FAN_AUTO = "AUTO"
|
||||
CONST_FAN_LOW = "LOW"
|
||||
CONST_FAN_MIDDLE = "MIDDLE"
|
||||
CONST_FAN_HIGH = "HIGH"
|
||||
|
||||
CONST_MODE_OFF = "OFF" # Switch off heating in a zone
|
||||
|
||||
# When we change the temperature setting, we need an overlay mode
|
||||
CONST_OVERLAY_TADO_MODE = "TADO_MODE" # wait until tado changes the mode automatic
|
||||
CONST_OVERLAY_MANUAL = "MANUAL" # the user has change the temperature or mode manually
|
||||
CONST_OVERLAY_TIMER = "TIMER" # the temperature will be reset after a timespan
|
||||
|
||||
|
||||
# Heat always comes first since we get the
|
||||
# min and max tempatures for the zone from
|
||||
# it.
|
||||
# Heat is preferred as it generally has a lower minimum temperature
|
||||
ORDERED_KNOWN_TADO_MODES = [
|
||||
CONST_MODE_HEAT,
|
||||
CONST_MODE_COOL,
|
||||
CONST_MODE_AUTO,
|
||||
CONST_MODE_DRY,
|
||||
CONST_MODE_FAN,
|
||||
]
|
||||
|
||||
TADO_MODES_TO_HA_CURRENT_HVAC_ACTION = {
|
||||
CONST_MODE_HEAT: CURRENT_HVAC_HEAT,
|
||||
CONST_MODE_DRY: CURRENT_HVAC_DRY,
|
||||
CONST_MODE_FAN: CURRENT_HVAC_FAN,
|
||||
CONST_MODE_COOL: CURRENT_HVAC_COOL,
|
||||
}
|
||||
|
||||
# These modes will not allow a temp to be set
|
||||
TADO_MODES_WITH_NO_TEMP_SETTING = [CONST_MODE_AUTO, CONST_MODE_DRY, CONST_MODE_FAN]
|
||||
#
|
||||
# HVAC_MODE_HEAT_COOL is mapped to CONST_MODE_AUTO
|
||||
# This lets tado decide on a temp
|
||||
#
|
||||
# HVAC_MODE_AUTO is mapped to CONST_MODE_SMART_SCHEDULE
|
||||
# This runs the smart schedule
|
||||
#
|
||||
HA_TO_TADO_HVAC_MODE_MAP = {
|
||||
HVAC_MODE_OFF: CONST_MODE_OFF,
|
||||
HVAC_MODE_HEAT_COOL: CONST_MODE_AUTO,
|
||||
HVAC_MODE_AUTO: CONST_MODE_SMART_SCHEDULE,
|
||||
HVAC_MODE_HEAT: CONST_MODE_HEAT,
|
||||
HVAC_MODE_COOL: CONST_MODE_COOL,
|
||||
HVAC_MODE_DRY: CONST_MODE_DRY,
|
||||
HVAC_MODE_FAN_ONLY: CONST_MODE_FAN,
|
||||
}
|
||||
|
||||
HA_TO_TADO_FAN_MODE_MAP = {
|
||||
FAN_AUTO: CONST_FAN_AUTO,
|
||||
FAN_OFF: CONST_FAN_OFF,
|
||||
FAN_LOW: CONST_FAN_LOW,
|
||||
FAN_MEDIUM: CONST_FAN_MIDDLE,
|
||||
FAN_HIGH: CONST_FAN_HIGH,
|
||||
}
|
||||
|
||||
TADO_TO_HA_HVAC_MODE_MAP = {
|
||||
value: key for key, value in HA_TO_TADO_HVAC_MODE_MAP.items()
|
||||
}
|
||||
|
||||
TADO_TO_HA_FAN_MODE_MAP = {value: key for key, value in HA_TO_TADO_FAN_MODE_MAP.items()}
|
||||
|
||||
DEFAULT_TADO_PRECISION = 0.1
|
||||
|
||||
SUPPORT_PRESET = [PRESET_AWAY, PRESET_HOME]
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
"name": "Tado",
|
||||
"documentation": "https://www.home-assistant.io/integrations/tado",
|
||||
"requirements": [
|
||||
"python-tado==0.4.0"
|
||||
"python-tado==0.3.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"codeowners": [
|
||||
"@michaelarnauts", "@bdraco"
|
||||
"@michaelarnauts"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ from homeassistant.helpers.entity import Entity
|
|||
|
||||
from . import DATA, DOMAIN, SIGNAL_TADO_UPDATE_RECEIVED
|
||||
from .const import TYPE_AIR_CONDITIONING, TYPE_HEATING, TYPE_HOT_WATER
|
||||
from .tado_adapter import TadoZoneData
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -51,7 +50,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
for zone in tado.zones:
|
||||
entities.extend(
|
||||
[
|
||||
create_zone_sensor(hass, tado, zone["name"], zone["id"], variable)
|
||||
create_zone_sensor(tado, zone["name"], zone["id"], variable)
|
||||
for variable in ZONE_SENSORS.get(zone["type"])
|
||||
]
|
||||
)
|
||||
|
@ -60,7 +59,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
for home in tado.devices:
|
||||
entities.extend(
|
||||
[
|
||||
create_device_sensor(hass, tado, home["name"], home["id"], variable)
|
||||
create_device_sensor(tado, home["name"], home["id"], variable)
|
||||
for variable in DEVICE_SENSORS
|
||||
]
|
||||
)
|
||||
|
@ -68,22 +67,21 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
add_entities(entities, True)
|
||||
|
||||
|
||||
def create_zone_sensor(hass, tado, name, zone_id, variable):
|
||||
def create_zone_sensor(tado, name, zone_id, variable):
|
||||
"""Create a zone sensor."""
|
||||
return TadoSensor(hass, tado, name, "zone", zone_id, variable)
|
||||
return TadoSensor(tado, name, "zone", zone_id, variable)
|
||||
|
||||
|
||||
def create_device_sensor(hass, tado, name, device_id, variable):
|
||||
def create_device_sensor(tado, name, device_id, variable):
|
||||
"""Create a device sensor."""
|
||||
return TadoSensor(hass, tado, name, "device", device_id, variable)
|
||||
return TadoSensor(tado, name, "device", device_id, variable)
|
||||
|
||||
|
||||
class TadoSensor(Entity):
|
||||
"""Representation of a tado Sensor."""
|
||||
|
||||
def __init__(self, hass, tado, zone_name, sensor_type, zone_id, zone_variable):
|
||||
def __init__(self, tado, zone_name, sensor_type, zone_id, zone_variable):
|
||||
"""Initialize of the Tado Sensor."""
|
||||
self.hass = hass
|
||||
self._tado = tado
|
||||
|
||||
self.zone_name = zone_name
|
||||
|
@ -95,16 +93,19 @@ class TadoSensor(Entity):
|
|||
|
||||
self._state = None
|
||||
self._state_attributes = None
|
||||
self._tado_zone_data = None
|
||||
self._async_update_zone_data()
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Register for sensor updates."""
|
||||
|
||||
@callback
|
||||
def async_update_callback():
|
||||
"""Schedule an entity update."""
|
||||
self.async_schedule_update_ha_state(True)
|
||||
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
SIGNAL_TADO_UPDATE_RECEIVED.format(self.sensor_type, self.zone_id),
|
||||
self._async_update_callback,
|
||||
async_update_callback,
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -148,74 +149,97 @@ class TadoSensor(Entity):
|
|||
return "mdi:water-percent"
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
def should_poll(self) -> bool:
|
||||
"""Do not poll."""
|
||||
return False
|
||||
|
||||
@callback
|
||||
def _async_update_callback(self):
|
||||
"""Update and write state."""
|
||||
self._async_update_zone_data()
|
||||
self.async_write_ha_state()
|
||||
|
||||
@callback
|
||||
def _async_update_zone_data(self):
|
||||
def update(self):
|
||||
"""Handle update callbacks."""
|
||||
try:
|
||||
data = self._tado.data[self.sensor_type][self.zone_id]
|
||||
except KeyError:
|
||||
return
|
||||
|
||||
self._tado_zone_data = TadoZoneData(data, self.zone_id)
|
||||
unit = TEMP_CELSIUS
|
||||
|
||||
if self.zone_variable == "temperature":
|
||||
self._state = self.hass.config.units.temperature(
|
||||
self._tado_zone_data.current_temp, TEMP_CELSIUS
|
||||
)
|
||||
self._state_attributes = {
|
||||
"time": self._tado_zone_data.current_temp_timestamp,
|
||||
"setting": 0, # setting is used in climate device
|
||||
}
|
||||
if "sensorDataPoints" in data:
|
||||
sensor_data = data["sensorDataPoints"]
|
||||
temperature = float(sensor_data["insideTemperature"]["celsius"])
|
||||
|
||||
self._state = self.hass.config.units.temperature(temperature, unit)
|
||||
self._state_attributes = {
|
||||
"time": sensor_data["insideTemperature"]["timestamp"],
|
||||
"setting": 0, # setting is used in climate device
|
||||
}
|
||||
|
||||
# temperature setting will not exist when device is off
|
||||
if (
|
||||
"temperature" in data["setting"]
|
||||
and data["setting"]["temperature"] is not None
|
||||
):
|
||||
temperature = float(data["setting"]["temperature"]["celsius"])
|
||||
|
||||
self._state_attributes[
|
||||
"setting"
|
||||
] = self.hass.config.units.temperature(temperature, unit)
|
||||
|
||||
elif self.zone_variable == "humidity":
|
||||
self._state = self._tado_zone_data.current_humidity
|
||||
self._state_attributes = {
|
||||
"time": self._tado_zone_data.current_humidity_timestamp
|
||||
}
|
||||
if "sensorDataPoints" in data:
|
||||
sensor_data = data["sensorDataPoints"]
|
||||
self._state = float(sensor_data["humidity"]["percentage"])
|
||||
self._state_attributes = {"time": sensor_data["humidity"]["timestamp"]}
|
||||
|
||||
elif self.zone_variable == "power":
|
||||
self._state = self._tado_zone_data.power
|
||||
if "setting" in data:
|
||||
self._state = data["setting"]["power"]
|
||||
|
||||
elif self.zone_variable == "link":
|
||||
self._state = self._tado_zone_data.link
|
||||
if "link" in data:
|
||||
self._state = data["link"]["state"]
|
||||
|
||||
elif self.zone_variable == "heating":
|
||||
self._state = self._tado_zone_data.heating_power_percentage
|
||||
self._state_attributes = {
|
||||
"time": self._tado_zone_data.heating_power_timestamp
|
||||
}
|
||||
if "activityDataPoints" in data:
|
||||
activity_data = data["activityDataPoints"]
|
||||
|
||||
if (
|
||||
"heatingPower" in activity_data
|
||||
and activity_data["heatingPower"] is not None
|
||||
):
|
||||
self._state = float(activity_data["heatingPower"]["percentage"])
|
||||
self._state_attributes = {
|
||||
"time": activity_data["heatingPower"]["timestamp"]
|
||||
}
|
||||
|
||||
elif self.zone_variable == "ac":
|
||||
self._state = self._tado_zone_data.ac_power
|
||||
self._state_attributes = {"time": self._tado_zone_data.ac_power_timestamp}
|
||||
if "activityDataPoints" in data:
|
||||
activity_data = data["activityDataPoints"]
|
||||
|
||||
if "acPower" in activity_data and activity_data["acPower"] is not None:
|
||||
self._state = activity_data["acPower"]["value"]
|
||||
self._state_attributes = {
|
||||
"time": activity_data["acPower"]["timestamp"]
|
||||
}
|
||||
|
||||
elif self.zone_variable == "tado bridge status":
|
||||
self._state = self._tado_zone_data.connection
|
||||
if "connectionState" in data:
|
||||
self._state = data["connectionState"]["value"]
|
||||
|
||||
elif self.zone_variable == "tado mode":
|
||||
self._state = self._tado_zone_data.tado_mode
|
||||
if "tadoMode" in data:
|
||||
self._state = data["tadoMode"]
|
||||
|
||||
elif self.zone_variable == "overlay":
|
||||
self._state = self._tado_zone_data.overlay_active
|
||||
self._state = "overlay" in data and data["overlay"] is not None
|
||||
self._state_attributes = (
|
||||
{"termination": self._tado_zone_data.overlay_termination_type}
|
||||
if self._tado_zone_data.overlay_active
|
||||
{"termination": data["overlay"]["termination"]["type"]}
|
||||
if self._state
|
||||
else {}
|
||||
)
|
||||
|
||||
elif self.zone_variable == "early start":
|
||||
self._state = self._tado_zone_data.preparation is not None
|
||||
self._state = "preparation" in data and data["preparation"] is not None
|
||||
|
||||
elif self.zone_variable == "open window":
|
||||
self._state = self._tado_zone_data.open_window is not None
|
||||
self._state_attributes = self._tado_zone_data.open_window_attr
|
||||
self._state = "openWindow" in data and data["openWindow"] is not None
|
||||
self._state_attributes = data["openWindow"] if self._state else {}
|
||||
|
|
|
@ -1,285 +0,0 @@
|
|||
"""Adapter to represent a tado zones and state."""
|
||||
import logging
|
||||
|
||||
from homeassistant.components.climate.const import (
|
||||
CURRENT_HVAC_COOL,
|
||||
CURRENT_HVAC_HEAT,
|
||||
CURRENT_HVAC_IDLE,
|
||||
CURRENT_HVAC_OFF,
|
||||
)
|
||||
|
||||
from .const import (
|
||||
CONST_FAN_AUTO,
|
||||
CONST_FAN_OFF,
|
||||
CONST_LINK_OFFLINE,
|
||||
CONST_MODE_OFF,
|
||||
CONST_MODE_SMART_SCHEDULE,
|
||||
DEFAULT_TADO_PRECISION,
|
||||
TADO_MODES_TO_HA_CURRENT_HVAC_ACTION,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TadoZoneData:
|
||||
"""Represent a tado zone."""
|
||||
|
||||
def __init__(self, data, zone_id):
|
||||
"""Create a tado zone."""
|
||||
self._data = data
|
||||
self._zone_id = zone_id
|
||||
self._current_temp = None
|
||||
self._connection = None
|
||||
self._current_temp_timestamp = None
|
||||
self._current_humidity = None
|
||||
self._is_away = False
|
||||
self._current_hvac_action = None
|
||||
self._current_tado_fan_speed = None
|
||||
self._current_tado_hvac_mode = None
|
||||
self._target_temp = None
|
||||
self._available = False
|
||||
self._power = None
|
||||
self._link = None
|
||||
self._ac_power_timestamp = None
|
||||
self._heating_power_timestamp = None
|
||||
self._ac_power = None
|
||||
self._heating_power = None
|
||||
self._heating_power_percentage = None
|
||||
self._tado_mode = None
|
||||
self._overlay_active = None
|
||||
self._overlay_termination_type = None
|
||||
self._preparation = None
|
||||
self._open_window = None
|
||||
self._open_window_attr = None
|
||||
self._precision = DEFAULT_TADO_PRECISION
|
||||
self.update_data(data)
|
||||
|
||||
@property
|
||||
def preparation(self):
|
||||
"""Zone is preparing to heat."""
|
||||
return self._preparation
|
||||
|
||||
@property
|
||||
def open_window(self):
|
||||
"""Window is open."""
|
||||
return self._open_window
|
||||
|
||||
@property
|
||||
def open_window_attr(self):
|
||||
"""Window open attributes."""
|
||||
return self._open_window_attr
|
||||
|
||||
@property
|
||||
def current_temp(self):
|
||||
"""Temperature of the zone."""
|
||||
return self._current_temp
|
||||
|
||||
@property
|
||||
def current_temp_timestamp(self):
|
||||
"""Temperature of the zone timestamp."""
|
||||
return self._current_temp_timestamp
|
||||
|
||||
@property
|
||||
def connection(self):
|
||||
"""Up or down internet connection."""
|
||||
return self._connection
|
||||
|
||||
@property
|
||||
def tado_mode(self):
|
||||
"""Tado mode."""
|
||||
return self._tado_mode
|
||||
|
||||
@property
|
||||
def overlay_active(self):
|
||||
"""Overlay acitive."""
|
||||
return self._current_tado_hvac_mode != CONST_MODE_SMART_SCHEDULE
|
||||
|
||||
@property
|
||||
def overlay_termination_type(self):
|
||||
"""Overlay termination type (what happens when period ends)."""
|
||||
return self._overlay_termination_type
|
||||
|
||||
@property
|
||||
def current_humidity(self):
|
||||
"""Humidity of the zone."""
|
||||
return self._current_humidity
|
||||
|
||||
@property
|
||||
def current_humidity_timestamp(self):
|
||||
"""Humidity of the zone timestamp."""
|
||||
return self._current_humidity_timestamp
|
||||
|
||||
@property
|
||||
def ac_power_timestamp(self):
|
||||
"""AC power timestamp."""
|
||||
return self._ac_power_timestamp
|
||||
|
||||
@property
|
||||
def heating_power_timestamp(self):
|
||||
"""Heating power timestamp."""
|
||||
return self._heating_power_timestamp
|
||||
|
||||
@property
|
||||
def ac_power(self):
|
||||
"""AC power."""
|
||||
return self._ac_power
|
||||
|
||||
@property
|
||||
def heating_power(self):
|
||||
"""Heating power."""
|
||||
return self._heating_power
|
||||
|
||||
@property
|
||||
def heating_power_percentage(self):
|
||||
"""Heating power percentage."""
|
||||
return self._heating_power_percentage
|
||||
|
||||
@property
|
||||
def is_away(self):
|
||||
"""Is Away (not home)."""
|
||||
return self._is_away
|
||||
|
||||
@property
|
||||
def power(self):
|
||||
"""Power is on."""
|
||||
return self._power
|
||||
|
||||
@property
|
||||
def current_hvac_action(self):
|
||||
"""HVAC Action (home assistant const)."""
|
||||
return self._current_hvac_action
|
||||
|
||||
@property
|
||||
def current_tado_fan_speed(self):
|
||||
"""TADO Fan speed (tado const)."""
|
||||
return self._current_tado_fan_speed
|
||||
|
||||
@property
|
||||
def link(self):
|
||||
"""Link (internet connection state)."""
|
||||
return self._link
|
||||
|
||||
@property
|
||||
def precision(self):
|
||||
"""Precision of temp units."""
|
||||
return self._precision
|
||||
|
||||
@property
|
||||
def current_tado_hvac_mode(self):
|
||||
"""TADO HVAC Mode (tado const)."""
|
||||
return self._current_tado_hvac_mode
|
||||
|
||||
@property
|
||||
def target_temp(self):
|
||||
"""Target temperature (C)."""
|
||||
return self._target_temp
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Device is available and link is up."""
|
||||
return self._available
|
||||
|
||||
def update_data(self, data):
|
||||
"""Handle update callbacks."""
|
||||
_LOGGER.debug("Updating climate platform for zone %d", self._zone_id)
|
||||
if "sensorDataPoints" in data:
|
||||
sensor_data = data["sensorDataPoints"]
|
||||
|
||||
if "insideTemperature" in sensor_data:
|
||||
temperature = float(sensor_data["insideTemperature"]["celsius"])
|
||||
self._current_temp = temperature
|
||||
self._current_temp_timestamp = sensor_data["insideTemperature"][
|
||||
"timestamp"
|
||||
]
|
||||
if "precision" in sensor_data["insideTemperature"]:
|
||||
self._precision = sensor_data["insideTemperature"]["precision"][
|
||||
"celsius"
|
||||
]
|
||||
|
||||
if "humidity" in sensor_data:
|
||||
humidity = float(sensor_data["humidity"]["percentage"])
|
||||
self._current_humidity = humidity
|
||||
self._current_humidity_timestamp = sensor_data["humidity"]["timestamp"]
|
||||
|
||||
self._is_away = None
|
||||
self._tado_mode = None
|
||||
if "tadoMode" in data:
|
||||
self._is_away = data["tadoMode"] == "AWAY"
|
||||
self._tado_mode = data["tadoMode"]
|
||||
|
||||
self._link = None
|
||||
if "link" in data:
|
||||
self._link = data["link"]["state"]
|
||||
|
||||
self._current_hvac_action = CURRENT_HVAC_OFF
|
||||
|
||||
if "setting" in data:
|
||||
# temperature setting will not exist when device is off
|
||||
if (
|
||||
"temperature" in data["setting"]
|
||||
and data["setting"]["temperature"] is not None
|
||||
):
|
||||
setting = float(data["setting"]["temperature"]["celsius"])
|
||||
self._target_temp = setting
|
||||
|
||||
setting = data["setting"]
|
||||
|
||||
self._current_tado_fan_speed = CONST_FAN_OFF
|
||||
# If there is no overlay, the mode will always be
|
||||
# "SMART_SCHEDULE"
|
||||
if "mode" in setting:
|
||||
self._current_tado_hvac_mode = setting["mode"]
|
||||
else:
|
||||
self._current_tado_hvac_mode = CONST_MODE_OFF
|
||||
|
||||
self._power = setting["power"]
|
||||
if self._power == "ON":
|
||||
# Not all devices have fans
|
||||
self._current_tado_fan_speed = setting.get("fanSpeed", CONST_FAN_AUTO)
|
||||
self._current_hvac_action = CURRENT_HVAC_IDLE
|
||||
|
||||
self._preparation = "preparation" in data and data["preparation"] is not None
|
||||
self._open_window = "openWindow" in data and data["openWindow"] is not None
|
||||
self._open_window_attr = data["openWindow"] if self._open_window else {}
|
||||
|
||||
if "activityDataPoints" in data:
|
||||
activity_data = data["activityDataPoints"]
|
||||
if "acPower" in activity_data and activity_data["acPower"] is not None:
|
||||
self._ac_power = activity_data["acPower"]["value"]
|
||||
self._ac_power_timestamp = activity_data["acPower"]["timestamp"]
|
||||
if activity_data["acPower"]["value"] == "ON" and self._power == "ON":
|
||||
# acPower means the unit has power so we need to map the mode
|
||||
self._current_hvac_action = TADO_MODES_TO_HA_CURRENT_HVAC_ACTION.get(
|
||||
self._current_tado_hvac_mode, CURRENT_HVAC_COOL
|
||||
)
|
||||
if (
|
||||
"heatingPower" in activity_data
|
||||
and activity_data["heatingPower"] is not None
|
||||
):
|
||||
self._heating_power = activity_data["heatingPower"].get("value", None)
|
||||
self._heating_power_timestamp = activity_data["heatingPower"][
|
||||
"timestamp"
|
||||
]
|
||||
self._heating_power_percentage = float(
|
||||
activity_data["heatingPower"].get("percentage", 0)
|
||||
)
|
||||
|
||||
if self._heating_power_percentage > 0.0 and self._power == "ON":
|
||||
self._current_hvac_action = CURRENT_HVAC_HEAT
|
||||
|
||||
# If there is no overlay
|
||||
# then we are running the smart schedule
|
||||
self._overlay_termination_type = None
|
||||
if "overlay" in data and data["overlay"] is not None:
|
||||
if (
|
||||
"termination" in data["overlay"]
|
||||
and "type" in data["overlay"]["termination"]
|
||||
):
|
||||
self._overlay_termination_type = data["overlay"]["termination"]["type"]
|
||||
else:
|
||||
self._current_tado_hvac_mode = CONST_MODE_SMART_SCHEDULE
|
||||
|
||||
self._connection = (
|
||||
data["connectionState"]["value"] if "connectionState" in data else None
|
||||
)
|
||||
self._available = self._link != CONST_LINK_OFFLINE
|
|
@ -12,7 +12,6 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|||
|
||||
from . import DOMAIN, SIGNAL_TADO_UPDATE_RECEIVED
|
||||
from .const import (
|
||||
CONST_MODE_HEAT,
|
||||
CONST_MODE_OFF,
|
||||
CONST_MODE_SMART_SCHEDULE,
|
||||
CONST_OVERLAY_MANUAL,
|
||||
|
@ -52,16 +51,14 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
for tado in api_list:
|
||||
for zone in tado.zones:
|
||||
if zone["type"] in [TYPE_HOT_WATER]:
|
||||
entity = create_water_heater_entity(
|
||||
hass, tado, zone["name"], zone["id"]
|
||||
)
|
||||
entity = create_water_heater_entity(tado, zone["name"], zone["id"])
|
||||
entities.append(entity)
|
||||
|
||||
if entities:
|
||||
add_entities(entities, True)
|
||||
|
||||
|
||||
def create_water_heater_entity(hass, tado, name: str, zone_id: int):
|
||||
def create_water_heater_entity(tado, name: str, zone_id: int):
|
||||
"""Create a Tado water heater device."""
|
||||
capabilities = tado.get_capabilities(zone_id)
|
||||
supports_temperature_control = capabilities["canSetTemperature"]
|
||||
|
@ -75,7 +72,7 @@ def create_water_heater_entity(hass, tado, name: str, zone_id: int):
|
|||
max_temp = None
|
||||
|
||||
entity = TadoWaterHeater(
|
||||
hass, tado, name, zone_id, supports_temperature_control, min_temp, max_temp
|
||||
tado, name, zone_id, supports_temperature_control, min_temp, max_temp
|
||||
)
|
||||
|
||||
return entity
|
||||
|
@ -86,7 +83,6 @@ class TadoWaterHeater(WaterHeaterDevice):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
hass,
|
||||
tado,
|
||||
zone_name,
|
||||
zone_id,
|
||||
|
@ -95,7 +91,6 @@ class TadoWaterHeater(WaterHeaterDevice):
|
|||
max_temp,
|
||||
):
|
||||
"""Initialize of Tado water heater entity."""
|
||||
self.hass = hass
|
||||
self._tado = tado
|
||||
|
||||
self.zone_name = zone_name
|
||||
|
@ -115,17 +110,28 @@ class TadoWaterHeater(WaterHeaterDevice):
|
|||
if self._supports_temperature_control:
|
||||
self._supported_features |= SUPPORT_TARGET_TEMPERATURE
|
||||
|
||||
self._current_tado_heat_mode = CONST_MODE_SMART_SCHEDULE
|
||||
if tado.fallback:
|
||||
# Fallback to Smart Schedule at next Schedule switch
|
||||
self._default_overlay = CONST_OVERLAY_TADO_MODE
|
||||
else:
|
||||
# Don't fallback to Smart Schedule, but keep in manual mode
|
||||
self._default_overlay = CONST_OVERLAY_MANUAL
|
||||
|
||||
self._current_operation = CONST_MODE_SMART_SCHEDULE
|
||||
self._overlay_mode = CONST_MODE_SMART_SCHEDULE
|
||||
self._async_update_data()
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Register for sensor updates."""
|
||||
|
||||
@callback
|
||||
def async_update_callback():
|
||||
"""Schedule an entity update."""
|
||||
self.async_schedule_update_ha_state(True)
|
||||
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
SIGNAL_TADO_UPDATE_RECEIVED.format("zone", self.zone_id),
|
||||
self._async_update_callback,
|
||||
async_update_callback,
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -151,7 +157,7 @@ class TadoWaterHeater(WaterHeaterDevice):
|
|||
@property
|
||||
def current_operation(self):
|
||||
"""Return current readable operation mode."""
|
||||
return WATER_HEATER_MAP_TADO.get(self._current_tado_heat_mode)
|
||||
return WATER_HEATER_MAP_TADO.get(self._current_operation)
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
|
@ -192,9 +198,16 @@ class TadoWaterHeater(WaterHeaterDevice):
|
|||
elif operation_mode == MODE_AUTO:
|
||||
mode = CONST_MODE_SMART_SCHEDULE
|
||||
elif operation_mode == MODE_HEAT:
|
||||
mode = CONST_MODE_HEAT
|
||||
mode = self._default_overlay
|
||||
|
||||
self._control_heater(heat_mode=mode)
|
||||
self._current_operation = mode
|
||||
self._overlay_mode = None
|
||||
|
||||
# Set a target temperature if we don't have any
|
||||
if mode == CONST_OVERLAY_TADO_MODE and self._target_temp is None:
|
||||
self._target_temp = self.min_temp
|
||||
|
||||
self._control_heater()
|
||||
|
||||
def set_temperature(self, **kwargs):
|
||||
"""Set new target temperature."""
|
||||
|
@ -202,17 +215,13 @@ class TadoWaterHeater(WaterHeaterDevice):
|
|||
if not self._supports_temperature_control or temperature is None:
|
||||
return
|
||||
|
||||
self._control_heater(target_temp=temperature)
|
||||
self._current_operation = self._default_overlay
|
||||
self._overlay_mode = None
|
||||
self._target_temp = temperature
|
||||
self._control_heater()
|
||||
|
||||
@callback
|
||||
def _async_update_callback(self):
|
||||
"""Load tado data and update state."""
|
||||
self._async_update_data()
|
||||
self.async_write_ha_state()
|
||||
|
||||
@callback
|
||||
def _async_update_data(self):
|
||||
"""Load tado data."""
|
||||
def update(self):
|
||||
"""Handle update callbacks."""
|
||||
_LOGGER.debug("Updating water_heater platform for zone %d", self.zone_id)
|
||||
data = self._tado.data["zone"][self.zone_id]
|
||||
|
||||
|
@ -223,70 +232,71 @@ class TadoWaterHeater(WaterHeaterDevice):
|
|||
if "setting" in data:
|
||||
power = data["setting"]["power"]
|
||||
if power == "OFF":
|
||||
self._current_tado_heat_mode = CONST_MODE_OFF
|
||||
self._current_operation = CONST_MODE_OFF
|
||||
# There is no overlay, the mode will always be
|
||||
# "SMART_SCHEDULE"
|
||||
self._overlay_mode = CONST_MODE_SMART_SCHEDULE
|
||||
self._device_is_active = False
|
||||
else:
|
||||
self._current_tado_heat_mode = CONST_MODE_HEAT
|
||||
self._device_is_active = True
|
||||
|
||||
# temperature setting will not exist when device is off
|
||||
if (
|
||||
"temperature" in data["setting"]
|
||||
and data["setting"]["temperature"] is not None
|
||||
):
|
||||
self._target_temp = float(data["setting"]["temperature"]["celsius"])
|
||||
setting = float(data["setting"]["temperature"]["celsius"])
|
||||
self._target_temp = setting
|
||||
|
||||
# If there is no overlay
|
||||
# then we are running the smart schedule
|
||||
if "overlay" in data and data["overlay"] is None:
|
||||
self._current_tado_heat_mode = CONST_MODE_SMART_SCHEDULE
|
||||
overlay = False
|
||||
overlay_data = None
|
||||
termination = CONST_MODE_SMART_SCHEDULE
|
||||
|
||||
self.async_write_ha_state()
|
||||
if "overlay" in data:
|
||||
overlay_data = data["overlay"]
|
||||
overlay = overlay_data is not None
|
||||
|
||||
def _control_heater(self, heat_mode=None, target_temp=None):
|
||||
if overlay:
|
||||
termination = overlay_data["termination"]["type"]
|
||||
|
||||
if self._device_is_active:
|
||||
# If you set mode manually to off, there will be an overlay
|
||||
# and a termination, but we want to see the mode "OFF"
|
||||
self._overlay_mode = termination
|
||||
self._current_operation = termination
|
||||
|
||||
def _control_heater(self):
|
||||
"""Send new target temperature."""
|
||||
|
||||
if heat_mode:
|
||||
self._current_tado_heat_mode = heat_mode
|
||||
|
||||
if target_temp:
|
||||
self._target_temp = target_temp
|
||||
|
||||
# Set a target temperature if we don't have any
|
||||
if self._target_temp is None:
|
||||
self._target_temp = self.min_temp
|
||||
|
||||
if self._current_tado_heat_mode == CONST_MODE_SMART_SCHEDULE:
|
||||
if self._current_operation == CONST_MODE_SMART_SCHEDULE:
|
||||
_LOGGER.debug(
|
||||
"Switching to SMART_SCHEDULE for zone %s (%d)",
|
||||
self.zone_name,
|
||||
self.zone_id,
|
||||
)
|
||||
self._tado.reset_zone_overlay(self.zone_id)
|
||||
self._overlay_mode = self._current_operation
|
||||
return
|
||||
|
||||
if self._current_tado_heat_mode == CONST_MODE_OFF:
|
||||
if self._current_operation == CONST_MODE_OFF:
|
||||
_LOGGER.debug(
|
||||
"Switching to OFF for zone %s (%d)", self.zone_name, self.zone_id
|
||||
)
|
||||
self._tado.set_zone_off(self.zone_id, CONST_OVERLAY_MANUAL, TYPE_HOT_WATER)
|
||||
self._overlay_mode = self._current_operation
|
||||
return
|
||||
|
||||
# Fallback to Smart Schedule at next Schedule switch if we have fallback enabled
|
||||
overlay_mode = (
|
||||
CONST_OVERLAY_TADO_MODE if self._tado.fallback else CONST_OVERLAY_MANUAL
|
||||
)
|
||||
|
||||
_LOGGER.debug(
|
||||
"Switching to %s for zone %s (%d) with temperature %s",
|
||||
self._current_tado_heat_mode,
|
||||
self._current_operation,
|
||||
self.zone_name,
|
||||
self.zone_id,
|
||||
self._target_temp,
|
||||
)
|
||||
self._tado.set_zone_overlay(
|
||||
zone_id=self.zone_id,
|
||||
overlay_mode=overlay_mode,
|
||||
temperature=self._target_temp,
|
||||
duration=None,
|
||||
device_type=TYPE_HOT_WATER,
|
||||
self.zone_id,
|
||||
self._current_operation,
|
||||
self._target_temp,
|
||||
None,
|
||||
TYPE_HOT_WATER,
|
||||
)
|
||||
self._overlay_mode = self._current_tado_heat_mode
|
||||
self._overlay_mode = self._current_operation
|
||||
|
|
|
@ -1650,7 +1650,7 @@ python-songpal==0.11.2
|
|||
python-synology==0.4.0
|
||||
|
||||
# homeassistant.components.tado
|
||||
python-tado==0.4.0
|
||||
python-tado==0.3.0
|
||||
|
||||
# homeassistant.components.telegram_bot
|
||||
python-telegram-bot==11.1.0
|
||||
|
|
|
@ -580,9 +580,6 @@ python-miio==0.4.8
|
|||
# homeassistant.components.nest
|
||||
python-nest==4.1.0
|
||||
|
||||
# homeassistant.components.tado
|
||||
python-tado==0.4.0
|
||||
|
||||
# homeassistant.components.twitch
|
||||
python-twitch-client==0.6.0
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
"""Mocks for the tado component."""
|
||||
import json
|
||||
import os
|
||||
|
||||
from homeassistant.components.tado.tado_adapter import TadoZoneData
|
||||
|
||||
from tests.common import load_fixture
|
||||
|
||||
|
||||
async def _mock_tado_climate_zone_from_fixture(hass, file):
|
||||
return TadoZoneData(await _load_json_fixture(hass, file), 1)
|
||||
|
||||
|
||||
async def _load_json_fixture(hass, path):
|
||||
fixture = await hass.async_add_executor_job(
|
||||
load_fixture, os.path.join("tado", path)
|
||||
)
|
||||
return json.loads(fixture)
|
|
@ -1,423 +0,0 @@
|
|||
"""The tado_adapter tests for the tado platform."""
|
||||
|
||||
|
||||
from tests.components.tado.mocks import _mock_tado_climate_zone_from_fixture
|
||||
|
||||
|
||||
async def test_ac_issue_32294_heat_mode(hass):
|
||||
"""Test smart ac cool mode."""
|
||||
ac_issue_32294_heat_mode = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "ac_issue_32294.heat_mode.json"
|
||||
)
|
||||
assert ac_issue_32294_heat_mode.preparation is False
|
||||
assert ac_issue_32294_heat_mode.open_window is False
|
||||
assert ac_issue_32294_heat_mode.open_window_attr == {}
|
||||
assert ac_issue_32294_heat_mode.current_temp == 21.82
|
||||
assert ac_issue_32294_heat_mode.current_temp_timestamp == "2020-02-29T22:51:05.016Z"
|
||||
assert ac_issue_32294_heat_mode.connection is None
|
||||
assert ac_issue_32294_heat_mode.tado_mode == "HOME"
|
||||
assert ac_issue_32294_heat_mode.overlay_active is False
|
||||
assert ac_issue_32294_heat_mode.overlay_termination_type is None
|
||||
assert ac_issue_32294_heat_mode.current_humidity == 40.4
|
||||
assert (
|
||||
ac_issue_32294_heat_mode.current_humidity_timestamp
|
||||
== "2020-02-29T22:51:05.016Z"
|
||||
)
|
||||
assert ac_issue_32294_heat_mode.ac_power_timestamp == "2020-02-29T22:50:34.850Z"
|
||||
assert ac_issue_32294_heat_mode.heating_power_timestamp is None
|
||||
assert ac_issue_32294_heat_mode.ac_power == "ON"
|
||||
assert ac_issue_32294_heat_mode.heating_power is None
|
||||
assert ac_issue_32294_heat_mode.heating_power_percentage is None
|
||||
assert ac_issue_32294_heat_mode.is_away is False
|
||||
assert ac_issue_32294_heat_mode.power == "ON"
|
||||
assert ac_issue_32294_heat_mode.current_hvac_action == "heating"
|
||||
assert ac_issue_32294_heat_mode.current_tado_fan_speed == "AUTO"
|
||||
assert ac_issue_32294_heat_mode.link == "ONLINE"
|
||||
assert ac_issue_32294_heat_mode.current_tado_hvac_mode == "SMART_SCHEDULE"
|
||||
assert ac_issue_32294_heat_mode.target_temp == 25.0
|
||||
assert ac_issue_32294_heat_mode.available is True
|
||||
assert ac_issue_32294_heat_mode.precision == 0.1
|
||||
|
||||
|
||||
async def test_smartac3_smart_mode(hass):
|
||||
"""Test smart ac smart mode."""
|
||||
smartac3_smart_mode = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "smartac3.smart_mode.json"
|
||||
)
|
||||
assert smartac3_smart_mode.preparation is False
|
||||
assert smartac3_smart_mode.open_window is False
|
||||
assert smartac3_smart_mode.open_window_attr == {}
|
||||
assert smartac3_smart_mode.current_temp == 24.43
|
||||
assert smartac3_smart_mode.current_temp_timestamp == "2020-03-05T03:50:24.769Z"
|
||||
assert smartac3_smart_mode.connection is None
|
||||
assert smartac3_smart_mode.tado_mode == "HOME"
|
||||
assert smartac3_smart_mode.overlay_active is False
|
||||
assert smartac3_smart_mode.overlay_termination_type is None
|
||||
assert smartac3_smart_mode.current_humidity == 60.0
|
||||
assert smartac3_smart_mode.current_humidity_timestamp == "2020-03-05T03:50:24.769Z"
|
||||
assert smartac3_smart_mode.ac_power_timestamp == "2020-03-05T03:52:22.253Z"
|
||||
assert smartac3_smart_mode.heating_power_timestamp is None
|
||||
assert smartac3_smart_mode.ac_power == "OFF"
|
||||
assert smartac3_smart_mode.heating_power is None
|
||||
assert smartac3_smart_mode.heating_power_percentage is None
|
||||
assert smartac3_smart_mode.is_away is False
|
||||
assert smartac3_smart_mode.power == "ON"
|
||||
assert smartac3_smart_mode.current_hvac_action == "idle"
|
||||
assert smartac3_smart_mode.current_tado_fan_speed == "MIDDLE"
|
||||
assert smartac3_smart_mode.link == "ONLINE"
|
||||
assert smartac3_smart_mode.current_tado_hvac_mode == "SMART_SCHEDULE"
|
||||
assert smartac3_smart_mode.target_temp == 20.0
|
||||
assert smartac3_smart_mode.available is True
|
||||
assert smartac3_smart_mode.precision == 0.1
|
||||
|
||||
|
||||
async def test_smartac3_cool_mode(hass):
|
||||
"""Test smart ac cool mode."""
|
||||
smartac3_cool_mode = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "smartac3.cool_mode.json"
|
||||
)
|
||||
assert smartac3_cool_mode.preparation is False
|
||||
assert smartac3_cool_mode.open_window is False
|
||||
assert smartac3_cool_mode.open_window_attr == {}
|
||||
assert smartac3_cool_mode.current_temp == 24.76
|
||||
assert smartac3_cool_mode.current_temp_timestamp == "2020-03-05T03:57:38.850Z"
|
||||
assert smartac3_cool_mode.connection is None
|
||||
assert smartac3_cool_mode.tado_mode == "HOME"
|
||||
assert smartac3_cool_mode.overlay_active is True
|
||||
assert smartac3_cool_mode.overlay_termination_type == "TADO_MODE"
|
||||
assert smartac3_cool_mode.current_humidity == 60.9
|
||||
assert smartac3_cool_mode.current_humidity_timestamp == "2020-03-05T03:57:38.850Z"
|
||||
assert smartac3_cool_mode.ac_power_timestamp == "2020-03-05T04:01:07.162Z"
|
||||
assert smartac3_cool_mode.heating_power_timestamp is None
|
||||
assert smartac3_cool_mode.ac_power == "ON"
|
||||
assert smartac3_cool_mode.heating_power is None
|
||||
assert smartac3_cool_mode.heating_power_percentage is None
|
||||
assert smartac3_cool_mode.is_away is False
|
||||
assert smartac3_cool_mode.power == "ON"
|
||||
assert smartac3_cool_mode.current_hvac_action == "cooling"
|
||||
assert smartac3_cool_mode.current_tado_fan_speed == "AUTO"
|
||||
assert smartac3_cool_mode.link == "ONLINE"
|
||||
assert smartac3_cool_mode.current_tado_hvac_mode == "COOL"
|
||||
assert smartac3_cool_mode.target_temp == 17.78
|
||||
assert smartac3_cool_mode.available is True
|
||||
assert smartac3_cool_mode.precision == 0.1
|
||||
|
||||
|
||||
async def test_smartac3_auto_mode(hass):
|
||||
"""Test smart ac cool mode."""
|
||||
smartac3_auto_mode = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "smartac3.auto_mode.json"
|
||||
)
|
||||
assert smartac3_auto_mode.preparation is False
|
||||
assert smartac3_auto_mode.open_window is False
|
||||
assert smartac3_auto_mode.open_window_attr == {}
|
||||
assert smartac3_auto_mode.current_temp == 24.8
|
||||
assert smartac3_auto_mode.current_temp_timestamp == "2020-03-05T03:55:38.160Z"
|
||||
assert smartac3_auto_mode.connection is None
|
||||
assert smartac3_auto_mode.tado_mode == "HOME"
|
||||
assert smartac3_auto_mode.overlay_active is True
|
||||
assert smartac3_auto_mode.overlay_termination_type == "TADO_MODE"
|
||||
assert smartac3_auto_mode.current_humidity == 62.5
|
||||
assert smartac3_auto_mode.current_humidity_timestamp == "2020-03-05T03:55:38.160Z"
|
||||
assert smartac3_auto_mode.ac_power_timestamp == "2020-03-05T03:56:38.627Z"
|
||||
assert smartac3_auto_mode.heating_power_timestamp is None
|
||||
assert smartac3_auto_mode.ac_power == "ON"
|
||||
assert smartac3_auto_mode.heating_power is None
|
||||
assert smartac3_auto_mode.heating_power_percentage is None
|
||||
assert smartac3_auto_mode.is_away is False
|
||||
assert smartac3_auto_mode.power == "ON"
|
||||
assert smartac3_auto_mode.current_hvac_action == "cooling"
|
||||
assert smartac3_auto_mode.current_tado_fan_speed == "AUTO"
|
||||
assert smartac3_auto_mode.link == "ONLINE"
|
||||
assert smartac3_auto_mode.current_tado_hvac_mode == "AUTO"
|
||||
assert smartac3_auto_mode.target_temp is None
|
||||
assert smartac3_auto_mode.available is True
|
||||
assert smartac3_auto_mode.precision == 0.1
|
||||
|
||||
|
||||
async def test_smartac3_dry_mode(hass):
|
||||
"""Test smart ac cool mode."""
|
||||
smartac3_dry_mode = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "smartac3.dry_mode.json"
|
||||
)
|
||||
assert smartac3_dry_mode.preparation is False
|
||||
assert smartac3_dry_mode.open_window is False
|
||||
assert smartac3_dry_mode.open_window_attr == {}
|
||||
assert smartac3_dry_mode.current_temp == 25.01
|
||||
assert smartac3_dry_mode.current_temp_timestamp == "2020-03-05T04:02:07.396Z"
|
||||
assert smartac3_dry_mode.connection is None
|
||||
assert smartac3_dry_mode.tado_mode == "HOME"
|
||||
assert smartac3_dry_mode.overlay_active is True
|
||||
assert smartac3_dry_mode.overlay_termination_type == "TADO_MODE"
|
||||
assert smartac3_dry_mode.current_humidity == 62.0
|
||||
assert smartac3_dry_mode.current_humidity_timestamp == "2020-03-05T04:02:07.396Z"
|
||||
assert smartac3_dry_mode.ac_power_timestamp == "2020-03-05T04:02:40.867Z"
|
||||
assert smartac3_dry_mode.heating_power_timestamp is None
|
||||
assert smartac3_dry_mode.ac_power == "ON"
|
||||
assert smartac3_dry_mode.heating_power is None
|
||||
assert smartac3_dry_mode.heating_power_percentage is None
|
||||
assert smartac3_dry_mode.is_away is False
|
||||
assert smartac3_dry_mode.power == "ON"
|
||||
assert smartac3_dry_mode.current_hvac_action == "drying"
|
||||
assert smartac3_dry_mode.current_tado_fan_speed == "AUTO"
|
||||
assert smartac3_dry_mode.link == "ONLINE"
|
||||
assert smartac3_dry_mode.current_tado_hvac_mode == "DRY"
|
||||
assert smartac3_dry_mode.target_temp is None
|
||||
assert smartac3_dry_mode.available is True
|
||||
assert smartac3_dry_mode.precision == 0.1
|
||||
|
||||
|
||||
async def test_smartac3_fan_mode(hass):
|
||||
"""Test smart ac cool mode."""
|
||||
smartac3_fan_mode = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "smartac3.fan_mode.json"
|
||||
)
|
||||
assert smartac3_fan_mode.preparation is False
|
||||
assert smartac3_fan_mode.open_window is False
|
||||
assert smartac3_fan_mode.open_window_attr == {}
|
||||
assert smartac3_fan_mode.current_temp == 25.01
|
||||
assert smartac3_fan_mode.current_temp_timestamp == "2020-03-05T04:02:07.396Z"
|
||||
assert smartac3_fan_mode.connection is None
|
||||
assert smartac3_fan_mode.tado_mode == "HOME"
|
||||
assert smartac3_fan_mode.overlay_active is True
|
||||
assert smartac3_fan_mode.overlay_termination_type == "TADO_MODE"
|
||||
assert smartac3_fan_mode.current_humidity == 62.0
|
||||
assert smartac3_fan_mode.current_humidity_timestamp == "2020-03-05T04:02:07.396Z"
|
||||
assert smartac3_fan_mode.ac_power_timestamp == "2020-03-05T04:03:44.328Z"
|
||||
assert smartac3_fan_mode.heating_power_timestamp is None
|
||||
assert smartac3_fan_mode.ac_power == "ON"
|
||||
assert smartac3_fan_mode.heating_power is None
|
||||
assert smartac3_fan_mode.heating_power_percentage is None
|
||||
assert smartac3_fan_mode.is_away is False
|
||||
assert smartac3_fan_mode.power == "ON"
|
||||
assert smartac3_fan_mode.current_hvac_action == "fan"
|
||||
assert smartac3_fan_mode.current_tado_fan_speed == "AUTO"
|
||||
assert smartac3_fan_mode.link == "ONLINE"
|
||||
assert smartac3_fan_mode.current_tado_hvac_mode == "FAN"
|
||||
assert smartac3_fan_mode.target_temp is None
|
||||
assert smartac3_fan_mode.available is True
|
||||
assert smartac3_fan_mode.precision == 0.1
|
||||
|
||||
|
||||
async def test_smartac3_heat_mode(hass):
|
||||
"""Test smart ac cool mode."""
|
||||
smartac3_heat_mode = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "smartac3.heat_mode.json"
|
||||
)
|
||||
assert smartac3_heat_mode.preparation is False
|
||||
assert smartac3_heat_mode.open_window is False
|
||||
assert smartac3_heat_mode.open_window_attr == {}
|
||||
assert smartac3_heat_mode.current_temp == 24.76
|
||||
assert smartac3_heat_mode.current_temp_timestamp == "2020-03-05T03:57:38.850Z"
|
||||
assert smartac3_heat_mode.connection is None
|
||||
assert smartac3_heat_mode.tado_mode == "HOME"
|
||||
assert smartac3_heat_mode.overlay_active is True
|
||||
assert smartac3_heat_mode.overlay_termination_type == "TADO_MODE"
|
||||
assert smartac3_heat_mode.current_humidity == 60.9
|
||||
assert smartac3_heat_mode.current_humidity_timestamp == "2020-03-05T03:57:38.850Z"
|
||||
assert smartac3_heat_mode.ac_power_timestamp == "2020-03-05T03:59:36.390Z"
|
||||
assert smartac3_heat_mode.heating_power_timestamp is None
|
||||
assert smartac3_heat_mode.ac_power == "ON"
|
||||
assert smartac3_heat_mode.heating_power is None
|
||||
assert smartac3_heat_mode.heating_power_percentage is None
|
||||
assert smartac3_heat_mode.is_away is False
|
||||
assert smartac3_heat_mode.power == "ON"
|
||||
assert smartac3_heat_mode.current_hvac_action == "heating"
|
||||
assert smartac3_heat_mode.current_tado_fan_speed == "AUTO"
|
||||
assert smartac3_heat_mode.link == "ONLINE"
|
||||
assert smartac3_heat_mode.current_tado_hvac_mode == "HEAT"
|
||||
assert smartac3_heat_mode.target_temp == 16.11
|
||||
assert smartac3_heat_mode.available is True
|
||||
assert smartac3_heat_mode.precision == 0.1
|
||||
|
||||
|
||||
async def test_smartac3_hvac_off(hass):
|
||||
"""Test smart ac cool mode."""
|
||||
smartac3_hvac_off = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "smartac3.hvac_off.json"
|
||||
)
|
||||
assert smartac3_hvac_off.preparation is False
|
||||
assert smartac3_hvac_off.open_window is False
|
||||
assert smartac3_hvac_off.open_window_attr == {}
|
||||
assert smartac3_hvac_off.current_temp == 21.44
|
||||
assert smartac3_hvac_off.current_temp_timestamp == "2020-03-05T01:21:44.089Z"
|
||||
assert smartac3_hvac_off.connection is None
|
||||
assert smartac3_hvac_off.tado_mode == "AWAY"
|
||||
assert smartac3_hvac_off.overlay_active is True
|
||||
assert smartac3_hvac_off.overlay_termination_type == "MANUAL"
|
||||
assert smartac3_hvac_off.current_humidity == 48.2
|
||||
assert smartac3_hvac_off.current_humidity_timestamp == "2020-03-05T01:21:44.089Z"
|
||||
assert smartac3_hvac_off.ac_power_timestamp == "2020-02-29T05:34:10.318Z"
|
||||
assert smartac3_hvac_off.heating_power_timestamp is None
|
||||
assert smartac3_hvac_off.ac_power == "OFF"
|
||||
assert smartac3_hvac_off.heating_power is None
|
||||
assert smartac3_hvac_off.heating_power_percentage is None
|
||||
assert smartac3_hvac_off.is_away is True
|
||||
assert smartac3_hvac_off.power == "OFF"
|
||||
assert smartac3_hvac_off.current_hvac_action == "off"
|
||||
assert smartac3_hvac_off.current_tado_fan_speed == "OFF"
|
||||
assert smartac3_hvac_off.link == "ONLINE"
|
||||
assert smartac3_hvac_off.current_tado_hvac_mode == "OFF"
|
||||
assert smartac3_hvac_off.target_temp is None
|
||||
assert smartac3_hvac_off.available is True
|
||||
assert smartac3_hvac_off.precision == 0.1
|
||||
|
||||
|
||||
async def test_smartac3_manual_off(hass):
|
||||
"""Test smart ac cool mode."""
|
||||
smartac3_manual_off = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "smartac3.manual_off.json"
|
||||
)
|
||||
assert smartac3_manual_off.preparation is False
|
||||
assert smartac3_manual_off.open_window is False
|
||||
assert smartac3_manual_off.open_window_attr == {}
|
||||
assert smartac3_manual_off.current_temp == 25.01
|
||||
assert smartac3_manual_off.current_temp_timestamp == "2020-03-05T04:02:07.396Z"
|
||||
assert smartac3_manual_off.connection is None
|
||||
assert smartac3_manual_off.tado_mode == "HOME"
|
||||
assert smartac3_manual_off.overlay_active is True
|
||||
assert smartac3_manual_off.overlay_termination_type == "MANUAL"
|
||||
assert smartac3_manual_off.current_humidity == 62.0
|
||||
assert smartac3_manual_off.current_humidity_timestamp == "2020-03-05T04:02:07.396Z"
|
||||
assert smartac3_manual_off.ac_power_timestamp == "2020-03-05T04:05:08.804Z"
|
||||
assert smartac3_manual_off.heating_power_timestamp is None
|
||||
assert smartac3_manual_off.ac_power == "OFF"
|
||||
assert smartac3_manual_off.heating_power is None
|
||||
assert smartac3_manual_off.heating_power_percentage is None
|
||||
assert smartac3_manual_off.is_away is False
|
||||
assert smartac3_manual_off.power == "OFF"
|
||||
assert smartac3_manual_off.current_hvac_action == "off"
|
||||
assert smartac3_manual_off.current_tado_fan_speed == "OFF"
|
||||
assert smartac3_manual_off.link == "ONLINE"
|
||||
assert smartac3_manual_off.current_tado_hvac_mode == "OFF"
|
||||
assert smartac3_manual_off.target_temp is None
|
||||
assert smartac3_manual_off.available is True
|
||||
assert smartac3_manual_off.precision == 0.1
|
||||
|
||||
|
||||
async def test_smartac3_offline(hass):
|
||||
"""Test smart ac cool mode."""
|
||||
smartac3_offline = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "smartac3.offline.json"
|
||||
)
|
||||
assert smartac3_offline.preparation is False
|
||||
assert smartac3_offline.open_window is False
|
||||
assert smartac3_offline.open_window_attr == {}
|
||||
assert smartac3_offline.current_temp == 25.05
|
||||
assert smartac3_offline.current_temp_timestamp == "2020-03-03T21:23:57.846Z"
|
||||
assert smartac3_offline.connection is None
|
||||
assert smartac3_offline.tado_mode == "HOME"
|
||||
assert smartac3_offline.overlay_active is True
|
||||
assert smartac3_offline.overlay_termination_type == "TADO_MODE"
|
||||
assert smartac3_offline.current_humidity == 61.6
|
||||
assert smartac3_offline.current_humidity_timestamp == "2020-03-03T21:23:57.846Z"
|
||||
assert smartac3_offline.ac_power_timestamp == "2020-02-29T18:42:26.683Z"
|
||||
assert smartac3_offline.heating_power_timestamp is None
|
||||
assert smartac3_offline.ac_power == "OFF"
|
||||
assert smartac3_offline.heating_power is None
|
||||
assert smartac3_offline.heating_power_percentage is None
|
||||
assert smartac3_offline.is_away is False
|
||||
assert smartac3_offline.power == "ON"
|
||||
assert smartac3_offline.current_hvac_action == "idle"
|
||||
assert smartac3_offline.current_tado_fan_speed == "AUTO"
|
||||
assert smartac3_offline.link == "OFFLINE"
|
||||
assert smartac3_offline.current_tado_hvac_mode == "COOL"
|
||||
assert smartac3_offline.target_temp == 17.78
|
||||
assert smartac3_offline.available is False
|
||||
assert smartac3_offline.precision == 0.1
|
||||
|
||||
|
||||
async def test_hvac_action_heat(hass):
|
||||
"""Test smart ac cool mode."""
|
||||
hvac_action_heat = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "hvac_action_heat.json"
|
||||
)
|
||||
assert hvac_action_heat.preparation is False
|
||||
assert hvac_action_heat.open_window is False
|
||||
assert hvac_action_heat.open_window_attr == {}
|
||||
assert hvac_action_heat.current_temp == 21.4
|
||||
assert hvac_action_heat.current_temp_timestamp == "2020-03-06T18:06:09.546Z"
|
||||
assert hvac_action_heat.connection is None
|
||||
assert hvac_action_heat.tado_mode == "HOME"
|
||||
assert hvac_action_heat.overlay_active is True
|
||||
assert hvac_action_heat.overlay_termination_type == "TADO_MODE"
|
||||
assert hvac_action_heat.current_humidity == 50.4
|
||||
assert hvac_action_heat.current_humidity_timestamp == "2020-03-06T18:06:09.546Z"
|
||||
assert hvac_action_heat.ac_power_timestamp == "2020-03-06T17:38:30.302Z"
|
||||
assert hvac_action_heat.heating_power_timestamp is None
|
||||
assert hvac_action_heat.ac_power == "OFF"
|
||||
assert hvac_action_heat.heating_power is None
|
||||
assert hvac_action_heat.heating_power_percentage is None
|
||||
assert hvac_action_heat.is_away is False
|
||||
assert hvac_action_heat.power == "ON"
|
||||
assert hvac_action_heat.current_hvac_action == "idle"
|
||||
assert hvac_action_heat.current_tado_fan_speed == "AUTO"
|
||||
assert hvac_action_heat.link == "ONLINE"
|
||||
assert hvac_action_heat.current_tado_hvac_mode == "HEAT"
|
||||
assert hvac_action_heat.target_temp == 16.11
|
||||
assert hvac_action_heat.available is True
|
||||
assert hvac_action_heat.precision == 0.1
|
||||
|
||||
|
||||
async def test_smartac3_turning_off(hass):
|
||||
"""Test smart ac cool mode."""
|
||||
smartac3_turning_off = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "smartac3.turning_off.json"
|
||||
)
|
||||
assert smartac3_turning_off.preparation is False
|
||||
assert smartac3_turning_off.open_window is False
|
||||
assert smartac3_turning_off.open_window_attr == {}
|
||||
assert smartac3_turning_off.current_temp == 21.4
|
||||
assert smartac3_turning_off.current_temp_timestamp == "2020-03-06T19:06:13.185Z"
|
||||
assert smartac3_turning_off.connection is None
|
||||
assert smartac3_turning_off.tado_mode == "HOME"
|
||||
assert smartac3_turning_off.overlay_active is True
|
||||
assert smartac3_turning_off.overlay_termination_type == "MANUAL"
|
||||
assert smartac3_turning_off.current_humidity == 49.2
|
||||
assert smartac3_turning_off.current_humidity_timestamp == "2020-03-06T19:06:13.185Z"
|
||||
assert smartac3_turning_off.ac_power_timestamp == "2020-03-06T19:05:21.835Z"
|
||||
assert smartac3_turning_off.heating_power_timestamp is None
|
||||
assert smartac3_turning_off.ac_power == "ON"
|
||||
assert smartac3_turning_off.heating_power is None
|
||||
assert smartac3_turning_off.heating_power_percentage is None
|
||||
assert smartac3_turning_off.is_away is False
|
||||
assert smartac3_turning_off.power == "OFF"
|
||||
assert smartac3_turning_off.current_hvac_action == "off"
|
||||
assert smartac3_turning_off.current_tado_fan_speed == "OFF"
|
||||
assert smartac3_turning_off.link == "ONLINE"
|
||||
assert smartac3_turning_off.current_tado_hvac_mode == "OFF"
|
||||
assert smartac3_turning_off.target_temp is None
|
||||
assert smartac3_turning_off.available is True
|
||||
assert smartac3_turning_off.precision == 0.1
|
||||
|
||||
|
||||
async def test_michael_heat_mode(hass):
|
||||
"""Test michael's tado."""
|
||||
michael_heat_mode = await _mock_tado_climate_zone_from_fixture(
|
||||
hass, "michael_heat_mode.json"
|
||||
)
|
||||
assert michael_heat_mode.preparation is False
|
||||
assert michael_heat_mode.open_window is False
|
||||
assert michael_heat_mode.open_window_attr == {}
|
||||
assert michael_heat_mode.current_temp == 20.06
|
||||
assert michael_heat_mode.current_temp_timestamp == "2020-03-09T08:16:49.271Z"
|
||||
assert michael_heat_mode.connection is None
|
||||
assert michael_heat_mode.tado_mode == "HOME"
|
||||
assert michael_heat_mode.overlay_active is False
|
||||
assert michael_heat_mode.overlay_termination_type is None
|
||||
assert michael_heat_mode.current_humidity == 41.8
|
||||
assert michael_heat_mode.current_humidity_timestamp == "2020-03-09T08:16:49.271Z"
|
||||
assert michael_heat_mode.ac_power_timestamp is None
|
||||
assert michael_heat_mode.heating_power_timestamp == "2020-03-09T08:20:47.299Z"
|
||||
assert michael_heat_mode.ac_power is None
|
||||
assert michael_heat_mode.heating_power is None
|
||||
assert michael_heat_mode.heating_power_percentage == 0.0
|
||||
assert michael_heat_mode.is_away is False
|
||||
assert michael_heat_mode.power == "ON"
|
||||
assert michael_heat_mode.current_hvac_action == "idle"
|
||||
assert michael_heat_mode.current_tado_fan_speed == "AUTO"
|
||||
assert michael_heat_mode.link == "ONLINE"
|
||||
assert michael_heat_mode.current_tado_hvac_mode == "SMART_SCHEDULE"
|
||||
assert michael_heat_mode.target_temp == 20.0
|
||||
assert michael_heat_mode.available is True
|
||||
assert michael_heat_mode.precision == 0.1
|
|
@ -1,60 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"fahrenheit": 71.28,
|
||||
"timestamp": "2020-02-29T22:51:05.016Z",
|
||||
"celsius": 21.82,
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"fahrenheit": 0.1,
|
||||
"celsius": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"timestamp": "2020-02-29T22:51:05.016Z",
|
||||
"percentage": 40.4,
|
||||
"type": "PERCENTAGE"
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"openWindow": null,
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"overlay": null,
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-02-29T22:50:34.850Z",
|
||||
"type": "POWER",
|
||||
"value": "ON"
|
||||
}
|
||||
},
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-01T00:00:00.000Z"
|
||||
},
|
||||
"preparation": null,
|
||||
"overlayType": null,
|
||||
"nextScheduleChange": {
|
||||
"start": "2020-03-01T00:00:00Z",
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "HEAT",
|
||||
"power": "ON",
|
||||
"temperature": {
|
||||
"fahrenheit": 59.0,
|
||||
"celsius": 15.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "HEAT",
|
||||
"power": "ON",
|
||||
"temperature": {
|
||||
"fahrenheit": 77.0,
|
||||
"celsius": 25.0
|
||||
}
|
||||
}
|
||||
}
|
67
tests/fixtures/tado/hvac_action_heat.json
vendored
67
tests/fixtures/tado/hvac_action_heat.json
vendored
|
@ -1,67 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"preparation": null,
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"power": "ON",
|
||||
"mode": "HEAT",
|
||||
"temperature": {
|
||||
"celsius": 16.11,
|
||||
"fahrenheit": 61.00
|
||||
},
|
||||
"fanSpeed": "AUTO"
|
||||
},
|
||||
"overlayType": "MANUAL",
|
||||
"overlay": {
|
||||
"type": "MANUAL",
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"power": "ON",
|
||||
"mode": "HEAT",
|
||||
"temperature": {
|
||||
"celsius": 16.11,
|
||||
"fahrenheit": 61.00
|
||||
},
|
||||
"fanSpeed": "AUTO"
|
||||
},
|
||||
"termination": {
|
||||
"type": "TADO_MODE",
|
||||
"typeSkillBasedApp": "TADO_MODE",
|
||||
"projectedExpiry": null
|
||||
}
|
||||
},
|
||||
"openWindow": null,
|
||||
"nextScheduleChange": null,
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-07T04:00:00.000Z"
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-03-06T17:38:30.302Z",
|
||||
"type": "POWER",
|
||||
"value": "OFF"
|
||||
}
|
||||
},
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"celsius": 21.40,
|
||||
"fahrenheit": 70.52,
|
||||
"timestamp": "2020-03-06T18:06:09.546Z",
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"celsius": 0.1,
|
||||
"fahrenheit": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"type": "PERCENTAGE",
|
||||
"percentage": 50.40,
|
||||
"timestamp": "2020-03-06T18:06:09.546Z"
|
||||
}
|
||||
}
|
||||
}
|
58
tests/fixtures/tado/michael_heat_mode.json
vendored
58
tests/fixtures/tado/michael_heat_mode.json
vendored
|
@ -1,58 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"preparation": null,
|
||||
"setting": {
|
||||
"type": "HEATING",
|
||||
"power": "ON",
|
||||
"temperature": {
|
||||
"celsius": 20.0,
|
||||
"fahrenheit": 68.0
|
||||
}
|
||||
},
|
||||
"overlayType": null,
|
||||
"overlay": null,
|
||||
"openWindow": null,
|
||||
"nextScheduleChange": {
|
||||
"start": "2020-03-09T17:00:00Z",
|
||||
"setting": {
|
||||
"type": "HEATING",
|
||||
"power": "ON",
|
||||
"temperature": {
|
||||
"celsius": 21.0,
|
||||
"fahrenheit": 69.8
|
||||
}
|
||||
}
|
||||
},
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-09T17:00:00.000Z"
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"activityDataPoints": {
|
||||
"heatingPower": {
|
||||
"type": "PERCENTAGE",
|
||||
"percentage": 0.0,
|
||||
"timestamp": "2020-03-09T08:20:47.299Z"
|
||||
}
|
||||
},
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"celsius": 20.06,
|
||||
"fahrenheit": 68.11,
|
||||
"timestamp": "2020-03-09T08:16:49.271Z",
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"celsius": 0.1,
|
||||
"fahrenheit": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"type": "PERCENTAGE",
|
||||
"percentage": 41.8,
|
||||
"timestamp": "2020-03-09T08:16:49.271Z"
|
||||
}
|
||||
}
|
||||
}
|
57
tests/fixtures/tado/smartac3.auto_mode.json
vendored
57
tests/fixtures/tado/smartac3.auto_mode.json
vendored
|
@ -1,57 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"fahrenheit": 76.64,
|
||||
"timestamp": "2020-03-05T03:55:38.160Z",
|
||||
"celsius": 24.8,
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"fahrenheit": 0.1,
|
||||
"celsius": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"timestamp": "2020-03-05T03:55:38.160Z",
|
||||
"percentage": 62.5,
|
||||
"type": "PERCENTAGE"
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"openWindow": null,
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"overlay": {
|
||||
"termination": {
|
||||
"typeSkillBasedApp": "TADO_MODE",
|
||||
"projectedExpiry": null,
|
||||
"type": "TADO_MODE"
|
||||
},
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "AUTO",
|
||||
"power": "ON"
|
||||
},
|
||||
"type": "MANUAL"
|
||||
},
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-03-05T03:56:38.627Z",
|
||||
"type": "POWER",
|
||||
"value": "ON"
|
||||
}
|
||||
},
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-05T08:00:00.000Z"
|
||||
},
|
||||
"preparation": null,
|
||||
"overlayType": "MANUAL",
|
||||
"nextScheduleChange": null,
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "AUTO",
|
||||
"power": "ON"
|
||||
}
|
||||
}
|
67
tests/fixtures/tado/smartac3.cool_mode.json
vendored
67
tests/fixtures/tado/smartac3.cool_mode.json
vendored
|
@ -1,67 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"fahrenheit": 76.57,
|
||||
"timestamp": "2020-03-05T03:57:38.850Z",
|
||||
"celsius": 24.76,
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"fahrenheit": 0.1,
|
||||
"celsius": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"timestamp": "2020-03-05T03:57:38.850Z",
|
||||
"percentage": 60.9,
|
||||
"type": "PERCENTAGE"
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"openWindow": null,
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"overlay": {
|
||||
"termination": {
|
||||
"typeSkillBasedApp": "TADO_MODE",
|
||||
"projectedExpiry": null,
|
||||
"type": "TADO_MODE"
|
||||
},
|
||||
"setting": {
|
||||
"fanSpeed": "AUTO",
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "COOL",
|
||||
"power": "ON",
|
||||
"temperature": {
|
||||
"fahrenheit": 64.0,
|
||||
"celsius": 17.78
|
||||
}
|
||||
},
|
||||
"type": "MANUAL"
|
||||
},
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-03-05T04:01:07.162Z",
|
||||
"type": "POWER",
|
||||
"value": "ON"
|
||||
}
|
||||
},
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-05T08:00:00.000Z"
|
||||
},
|
||||
"preparation": null,
|
||||
"overlayType": "MANUAL",
|
||||
"nextScheduleChange": null,
|
||||
"setting": {
|
||||
"fanSpeed": "AUTO",
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "COOL",
|
||||
"power": "ON",
|
||||
"temperature": {
|
||||
"fahrenheit": 64.0,
|
||||
"celsius": 17.78
|
||||
}
|
||||
}
|
||||
}
|
57
tests/fixtures/tado/smartac3.dry_mode.json
vendored
57
tests/fixtures/tado/smartac3.dry_mode.json
vendored
|
@ -1,57 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"fahrenheit": 77.02,
|
||||
"timestamp": "2020-03-05T04:02:07.396Z",
|
||||
"celsius": 25.01,
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"fahrenheit": 0.1,
|
||||
"celsius": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"timestamp": "2020-03-05T04:02:07.396Z",
|
||||
"percentage": 62.0,
|
||||
"type": "PERCENTAGE"
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"openWindow": null,
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"overlay": {
|
||||
"termination": {
|
||||
"typeSkillBasedApp": "TADO_MODE",
|
||||
"projectedExpiry": null,
|
||||
"type": "TADO_MODE"
|
||||
},
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "DRY",
|
||||
"power": "ON"
|
||||
},
|
||||
"type": "MANUAL"
|
||||
},
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-03-05T04:02:40.867Z",
|
||||
"type": "POWER",
|
||||
"value": "ON"
|
||||
}
|
||||
},
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-05T08:00:00.000Z"
|
||||
},
|
||||
"preparation": null,
|
||||
"overlayType": "MANUAL",
|
||||
"nextScheduleChange": null,
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "DRY",
|
||||
"power": "ON"
|
||||
}
|
||||
}
|
57
tests/fixtures/tado/smartac3.fan_mode.json
vendored
57
tests/fixtures/tado/smartac3.fan_mode.json
vendored
|
@ -1,57 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"fahrenheit": 77.02,
|
||||
"timestamp": "2020-03-05T04:02:07.396Z",
|
||||
"celsius": 25.01,
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"fahrenheit": 0.1,
|
||||
"celsius": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"timestamp": "2020-03-05T04:02:07.396Z",
|
||||
"percentage": 62.0,
|
||||
"type": "PERCENTAGE"
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"openWindow": null,
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"overlay": {
|
||||
"termination": {
|
||||
"typeSkillBasedApp": "TADO_MODE",
|
||||
"projectedExpiry": null,
|
||||
"type": "TADO_MODE"
|
||||
},
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "FAN",
|
||||
"power": "ON"
|
||||
},
|
||||
"type": "MANUAL"
|
||||
},
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-03-05T04:03:44.328Z",
|
||||
"type": "POWER",
|
||||
"value": "ON"
|
||||
}
|
||||
},
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-05T08:00:00.000Z"
|
||||
},
|
||||
"preparation": null,
|
||||
"overlayType": "MANUAL",
|
||||
"nextScheduleChange": null,
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "FAN",
|
||||
"power": "ON"
|
||||
}
|
||||
}
|
67
tests/fixtures/tado/smartac3.heat_mode.json
vendored
67
tests/fixtures/tado/smartac3.heat_mode.json
vendored
|
@ -1,67 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"fahrenheit": 76.57,
|
||||
"timestamp": "2020-03-05T03:57:38.850Z",
|
||||
"celsius": 24.76,
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"fahrenheit": 0.1,
|
||||
"celsius": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"timestamp": "2020-03-05T03:57:38.850Z",
|
||||
"percentage": 60.9,
|
||||
"type": "PERCENTAGE"
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"openWindow": null,
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"overlay": {
|
||||
"termination": {
|
||||
"typeSkillBasedApp": "TADO_MODE",
|
||||
"projectedExpiry": null,
|
||||
"type": "TADO_MODE"
|
||||
},
|
||||
"setting": {
|
||||
"fanSpeed": "AUTO",
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "HEAT",
|
||||
"power": "ON",
|
||||
"temperature": {
|
||||
"fahrenheit": 61.0,
|
||||
"celsius": 16.11
|
||||
}
|
||||
},
|
||||
"type": "MANUAL"
|
||||
},
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-03-05T03:59:36.390Z",
|
||||
"type": "POWER",
|
||||
"value": "ON"
|
||||
}
|
||||
},
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-05T08:00:00.000Z"
|
||||
},
|
||||
"preparation": null,
|
||||
"overlayType": "MANUAL",
|
||||
"nextScheduleChange": null,
|
||||
"setting": {
|
||||
"fanSpeed": "AUTO",
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "HEAT",
|
||||
"power": "ON",
|
||||
"temperature": {
|
||||
"fahrenheit": 61.0,
|
||||
"celsius": 16.11
|
||||
}
|
||||
}
|
||||
}
|
55
tests/fixtures/tado/smartac3.hvac_off.json
vendored
55
tests/fixtures/tado/smartac3.hvac_off.json
vendored
|
@ -1,55 +0,0 @@
|
|||
{
|
||||
"tadoMode": "AWAY",
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"fahrenheit": 70.59,
|
||||
"timestamp": "2020-03-05T01:21:44.089Z",
|
||||
"celsius": 21.44,
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"fahrenheit": 0.1,
|
||||
"celsius": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"timestamp": "2020-03-05T01:21:44.089Z",
|
||||
"percentage": 48.2,
|
||||
"type": "PERCENTAGE"
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"openWindow": null,
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"overlay": {
|
||||
"termination": {
|
||||
"typeSkillBasedApp": "MANUAL",
|
||||
"projectedExpiry": null,
|
||||
"type": "MANUAL"
|
||||
},
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"power": "OFF"
|
||||
},
|
||||
"type": "MANUAL"
|
||||
},
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-02-29T05:34:10.318Z",
|
||||
"type": "POWER",
|
||||
"value": "OFF"
|
||||
}
|
||||
},
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-05T04:00:00.000Z"
|
||||
},
|
||||
"preparation": null,
|
||||
"overlayType": "MANUAL",
|
||||
"nextScheduleChange": null,
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"power": "OFF"
|
||||
}
|
||||
}
|
55
tests/fixtures/tado/smartac3.manual_off.json
vendored
55
tests/fixtures/tado/smartac3.manual_off.json
vendored
|
@ -1,55 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"fahrenheit": 77.02,
|
||||
"timestamp": "2020-03-05T04:02:07.396Z",
|
||||
"celsius": 25.01,
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"fahrenheit": 0.1,
|
||||
"celsius": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"timestamp": "2020-03-05T04:02:07.396Z",
|
||||
"percentage": 62.0,
|
||||
"type": "PERCENTAGE"
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"openWindow": null,
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"overlay": {
|
||||
"termination": {
|
||||
"typeSkillBasedApp": "MANUAL",
|
||||
"projectedExpiry": null,
|
||||
"type": "MANUAL"
|
||||
},
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"power": "OFF"
|
||||
},
|
||||
"type": "MANUAL"
|
||||
},
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-03-05T04:05:08.804Z",
|
||||
"type": "POWER",
|
||||
"value": "OFF"
|
||||
}
|
||||
},
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-05T08:00:00.000Z"
|
||||
},
|
||||
"preparation": null,
|
||||
"overlayType": "MANUAL",
|
||||
"nextScheduleChange": null,
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"power": "OFF"
|
||||
}
|
||||
}
|
71
tests/fixtures/tado/smartac3.offline.json
vendored
71
tests/fixtures/tado/smartac3.offline.json
vendored
|
@ -1,71 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"fahrenheit": 77.09,
|
||||
"timestamp": "2020-03-03T21:23:57.846Z",
|
||||
"celsius": 25.05,
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"fahrenheit": 0.1,
|
||||
"celsius": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"timestamp": "2020-03-03T21:23:57.846Z",
|
||||
"percentage": 61.6,
|
||||
"type": "PERCENTAGE"
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"state": "OFFLINE",
|
||||
"reason": {
|
||||
"code": "disconnectedDevice",
|
||||
"title": "There is a disconnected device."
|
||||
}
|
||||
},
|
||||
"openWindow": null,
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"overlay": {
|
||||
"termination": {
|
||||
"typeSkillBasedApp": "TADO_MODE",
|
||||
"projectedExpiry": null,
|
||||
"type": "TADO_MODE"
|
||||
},
|
||||
"setting": {
|
||||
"fanSpeed": "AUTO",
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "COOL",
|
||||
"power": "ON",
|
||||
"temperature": {
|
||||
"fahrenheit": 64.0,
|
||||
"celsius": 17.78
|
||||
}
|
||||
},
|
||||
"type": "MANUAL"
|
||||
},
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-02-29T18:42:26.683Z",
|
||||
"type": "POWER",
|
||||
"value": "OFF"
|
||||
}
|
||||
},
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-05T08:00:00.000Z"
|
||||
},
|
||||
"preparation": null,
|
||||
"overlayType": "MANUAL",
|
||||
"nextScheduleChange": null,
|
||||
"setting": {
|
||||
"fanSpeed": "AUTO",
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "COOL",
|
||||
"power": "ON",
|
||||
"temperature": {
|
||||
"fahrenheit": 64.0,
|
||||
"celsius": 17.78
|
||||
}
|
||||
}
|
||||
}
|
50
tests/fixtures/tado/smartac3.smart_mode.json
vendored
50
tests/fixtures/tado/smartac3.smart_mode.json
vendored
|
@ -1,50 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"fahrenheit": 75.97,
|
||||
"timestamp": "2020-03-05T03:50:24.769Z",
|
||||
"celsius": 24.43,
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"fahrenheit": 0.1,
|
||||
"celsius": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"timestamp": "2020-03-05T03:50:24.769Z",
|
||||
"percentage": 60.0,
|
||||
"type": "PERCENTAGE"
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"openWindow": null,
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"overlay": null,
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-03-05T03:52:22.253Z",
|
||||
"type": "POWER",
|
||||
"value": "OFF"
|
||||
}
|
||||
},
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-05T08:00:00.000Z"
|
||||
},
|
||||
"preparation": null,
|
||||
"overlayType": null,
|
||||
"nextScheduleChange": null,
|
||||
"setting": {
|
||||
"fanSpeed": "MIDDLE",
|
||||
"type": "AIR_CONDITIONING",
|
||||
"mode": "COOL",
|
||||
"power": "ON",
|
||||
"temperature": {
|
||||
"fahrenheit": 68.0,
|
||||
"celsius": 20.0
|
||||
}
|
||||
}
|
||||
}
|
55
tests/fixtures/tado/smartac3.turning_off.json
vendored
55
tests/fixtures/tado/smartac3.turning_off.json
vendored
|
@ -1,55 +0,0 @@
|
|||
{
|
||||
"tadoMode": "HOME",
|
||||
"geolocationOverride": false,
|
||||
"geolocationOverrideDisableTime": null,
|
||||
"preparation": null,
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"power": "OFF"
|
||||
},
|
||||
"overlayType": "MANUAL",
|
||||
"overlay": {
|
||||
"type": "MANUAL",
|
||||
"setting": {
|
||||
"type": "AIR_CONDITIONING",
|
||||
"power": "OFF"
|
||||
},
|
||||
"termination": {
|
||||
"type": "MANUAL",
|
||||
"typeSkillBasedApp": "MANUAL",
|
||||
"projectedExpiry": null
|
||||
}
|
||||
},
|
||||
"openWindow": null,
|
||||
"nextScheduleChange": null,
|
||||
"nextTimeBlock": {
|
||||
"start": "2020-03-07T04:00:00.000Z"
|
||||
},
|
||||
"link": {
|
||||
"state": "ONLINE"
|
||||
},
|
||||
"activityDataPoints": {
|
||||
"acPower": {
|
||||
"timestamp": "2020-03-06T19:05:21.835Z",
|
||||
"type": "POWER",
|
||||
"value": "ON"
|
||||
}
|
||||
},
|
||||
"sensorDataPoints": {
|
||||
"insideTemperature": {
|
||||
"celsius": 21.40,
|
||||
"fahrenheit": 70.52,
|
||||
"timestamp": "2020-03-06T19:06:13.185Z",
|
||||
"type": "TEMPERATURE",
|
||||
"precision": {
|
||||
"celsius": 0.1,
|
||||
"fahrenheit": 0.1
|
||||
}
|
||||
},
|
||||
"humidity": {
|
||||
"type": "PERCENTAGE",
|
||||
"percentage": 49.20,
|
||||
"timestamp": "2020-03-06T19:06:13.185Z"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue