Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tado service set temperature offset #45014

Merged
merged 12 commits into from
Jan 26, 2021
14 changes: 14 additions & 0 deletions homeassistant/components/tado/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,13 @@ def update_sensor(self, sensor_type, sensor):
try:
if sensor_type == "device":
data = self.tado.getDeviceInfo(sensor)
if (
"INSIDE_TEMPERATURE_MEASUREMENT"
in data["characteristics"]["capabilities"]
):
data["TEMP_OFFSET"] = self.tado.getDeviceInfo(
sensor, "temperatureOffset"
)
elif sensor_type == "zone":
data = self.tado.getZoneState(sensor)
else:
Expand Down Expand Up @@ -303,3 +310,10 @@ def set_zone_off(self, zone_id, overlay_mode, device_type="HEATING"):
_LOGGER.error("Could not set zone overlay: %s", exc)

self.update_sensor("zone", zone_id)

def set_temperature_offset(self, device_id, offset):
"""Set temperature offset of device."""
try:
self.tado.setTempOffset(device_id, offset)
except RequestException as exc:
_LOGGER.error("Could not set temperature offset: %s", exc)
49 changes: 47 additions & 2 deletions homeassistant/components/tado/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@
vol.Required(ATTR_TEMPERATURE): vol.Coerce(float),
}

SERVICE_TEMP_OFFSET = "set_climate_temperature_offset"
ATTR_OFFSET = "offset"

CLIMATE_TEMP_OFFSET_SCHEMA = {
vol.Required(ATTR_OFFSET, default=0): vol.Coerce(float),
}


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities
Expand All @@ -80,6 +87,12 @@ async def async_setup_entry(
"set_timer",
)

platform.async_register_entity_service(
SERVICE_TEMP_OFFSET,
CLIMATE_TEMP_OFFSET_SCHEMA,
"set_temp_offset",
)

if entities:
async_add_entities(entities, True)

Expand All @@ -89,13 +102,15 @@ def _generate_entities(tado):
entities = []
for zone in tado.zones:
if zone["type"] in [TYPE_HEATING, TYPE_AIR_CONDITIONING]:
entity = create_climate_entity(tado, zone["name"], zone["id"])
entity = create_climate_entity(
tado, zone["name"], zone["id"], zone["devices"][0]
)
if entity:
entities.append(entity)
return entities


def create_climate_entity(tado, name: str, zone_id: int):
def create_climate_entity(tado, name: str, zone_id: int, device_info: dict):
"""Create a Tado climate entity."""
capabilities = tado.get_capabilities(zone_id)
_LOGGER.debug("Capabilities for zone %s: %s", zone_id, capabilities)
Expand Down Expand Up @@ -178,6 +193,7 @@ def create_climate_entity(tado, name: str, zone_id: int):
supported_hvac_modes,
supported_fan_modes,
support_flags,
device_info,
)
return entity

Expand All @@ -200,6 +216,7 @@ def __init__(
supported_hvac_modes,
supported_fan_modes,
support_flags,
device_info,
):
"""Initialize of Tado climate entity."""
self._tado = tado
Expand All @@ -208,6 +225,8 @@ def __init__(
self.zone_id = zone_id
self.zone_type = zone_type
self._unique_id = f"{zone_type} {zone_id} {tado.home_id}"
self._device_info = device_info
self._device_id = self._device_info["shortSerialNo"]

self._ac_device = zone_type == TYPE_AIR_CONDITIONING
self._supported_hvac_modes = supported_hvac_modes
Expand Down Expand Up @@ -236,6 +255,8 @@ def __init__(

self._tado_zone_data = None

self._tado_zone_temp_offset = dict()
MartinHjelmare marked this conversation as resolved.
Show resolved Hide resolved

self._async_update_zone_data()

async def async_added_to_hass(self):
Expand Down Expand Up @@ -362,6 +383,17 @@ def set_timer(self, time_period, temperature=None):
hvac_mode=CONST_MODE_HEAT, target_temp=temperature, duration=time_period
)

def set_temp_offset(self, offset):
"""Set offset on the entity."""

_LOGGER.debug(
"Setting temperature offset for device %s setting to (%d)",
self._device_id,
offset,
)

self._tado.set_temperature_offset(self._device_id, offset)

def set_temperature(self, **kwargs):
"""Set new target temperature."""
temperature = kwargs.get(ATTR_TEMPERATURE)
Expand Down Expand Up @@ -427,6 +459,11 @@ def swing_modes(self):
return [TADO_SWING_ON, TADO_SWING_OFF]
return None

@property
def device_state_attributes(self):
"""Return temperature offset."""
return self._tado_zone_temp_offset

def set_swing_mode(self, swing_mode):
"""Set swing modes for the device."""
self._control_hvac(swing_mode=swing_mode)
Expand All @@ -435,11 +472,19 @@ def set_swing_mode(self, swing_mode):
def _async_update_zone_data(self):
"""Load tado data into zone."""
self._tado_zone_data = self._tado.data["zone"][self.zone_id]
self._update_offset()
self._current_tado_fan_speed = self._tado_zone_data.current_fan_speed
self._current_tado_hvac_mode = self._tado_zone_data.current_hvac_mode
self._current_tado_hvac_action = self._tado_zone_data.current_hvac_action
self._current_tado_swing_mode = self._tado_zone_data.current_swing_mode

def _update_offset(self):
MartinHjelmare marked this conversation as resolved.
Show resolved Hide resolved
# Add 'offset' to the key so its named correctly as an attribute in HA
for key in self._tado.data["device"][self._device_id]["TEMP_OFFSET"]:
self._tado_zone_temp_offset["offset_" + key] = self._tado.data["device"][
MartinHjelmare marked this conversation as resolved.
Show resolved Hide resolved
self._device_id
]["TEMP_OFFSET"][key]

@callback
def _async_update_callback(self):
"""Load tado data and update state."""
Expand Down
10 changes: 10 additions & 0 deletions homeassistant/components/tado/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,13 @@ set_water_heater_timer:
temperature:
description: Temperature to set heater to
example: 25

set_climate_temperature_offset:
description: Set the temperature offset of climate entities
fields:
entity_id:
description: Entity ID for the tado component to set the temperature offset
example: climate.heating
offset:
description: Offset you would like, can be to 2 decimal places (depending on your device) positive or negative
example: -1.2