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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(climate): Support cooling #1691

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 55 additions & 57 deletions custom_components/localtuya/climate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Platform to locally control Tuya-based climate devices."""

import asyncio
import logging
from functools import partial
Expand All @@ -13,9 +14,11 @@
from homeassistant.components.climate.const import (
CURRENT_HVAC_HEAT,
CURRENT_HVAC_IDLE,
CURRENT_HVAC_COOL,
HVAC_MODE_AUTO,
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
HVAC_MODE_COOL,
PRESET_AWAY,
PRESET_ECO,
PRESET_HOME,
Expand All @@ -41,6 +44,8 @@
CONF_HVAC_ACTION_SET,
CONF_HVAC_MODE_DP,
CONF_HVAC_MODE_SET,
CONF_HVAC_MODE_COOLING_DP,
CONF_HVAC_MODE_COOLING_SET,
CONF_MAX_TEMP_DP,
CONF_MIN_TEMP_DP,
CONF_PRECISION,
Expand Down Expand Up @@ -78,6 +83,13 @@
HVAC_MODE_AUTO: "0",
},
}
HVAC_MODE_COOLING_SETS = {
"True/False": {
HVAC_MODE_HEAT: True,
HVAC_MODE_COOL: False,
},
}

HVAC_ACTION_SETS = {
"True/False": {
CURRENT_HVAC_HEAT: True,
Expand Down Expand Up @@ -118,28 +130,22 @@ def flow_schema(dps):
return {
vol.Optional(CONF_TARGET_TEMPERATURE_DP): vol.In(dps),
vol.Optional(CONF_CURRENT_TEMPERATURE_DP): vol.In(dps),
vol.Optional(CONF_TEMPERATURE_STEP): vol.In(
[PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS]
),
vol.Optional(CONF_TEMPERATURE_STEP): vol.In([PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS]),
vol.Optional(CONF_MAX_TEMP_DP): vol.In(dps),
vol.Optional(CONF_MIN_TEMP_DP): vol.In(dps),
vol.Optional(CONF_PRECISION): vol.In(
[PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS]
),
vol.Optional(CONF_PRECISION): vol.In([PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS]),
vol.Optional(CONF_HVAC_MODE_DP): vol.In(dps),
vol.Optional(CONF_HVAC_MODE_SET): vol.In(list(HVAC_MODE_SETS.keys())),
vol.Optional(CONF_HVAC_MODE_COOLING_DP): vol.In(dps),
vol.Optional(CONF_HVAC_MODE_COOLING_SET): vol.In(list(HVAC_MODE_COOLING_SETS.keys())),
vol.Optional(CONF_HVAC_ACTION_DP): vol.In(dps),
vol.Optional(CONF_HVAC_ACTION_SET): vol.In(list(HVAC_ACTION_SETS.keys())),
vol.Optional(CONF_ECO_DP): vol.In(dps),
vol.Optional(CONF_ECO_VALUE): str,
vol.Optional(CONF_PRESET_DP): vol.In(dps),
vol.Optional(CONF_PRESET_SET): vol.In(list(PRESET_SETS.keys())),
vol.Optional(CONF_TEMPERATURE_UNIT): vol.In(
[TEMPERATURE_CELSIUS, TEMPERATURE_FAHRENHEIT]
),
vol.Optional(CONF_TARGET_PRECISION): vol.In(
[PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS]
),
vol.Optional(CONF_TEMPERATURE_UNIT): vol.In([TEMPERATURE_CELSIUS, TEMPERATURE_FAHRENHEIT]),
vol.Optional(CONF_TARGET_PRECISION): vol.In([PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS]),
vol.Optional(CONF_HEURISTIC_ACTION): bool,
}

Expand All @@ -163,24 +169,18 @@ def __init__(
self._preset_mode = None
self._hvac_action = None
self._precision = self._config.get(CONF_PRECISION, DEFAULT_PRECISION)
self._target_precision = self._config.get(
CONF_TARGET_PRECISION, self._precision
)
self._target_precision = self._config.get(CONF_TARGET_PRECISION, self._precision)
self._conf_hvac_mode_dp = self._config.get(CONF_HVAC_MODE_DP)
self._conf_hvac_mode_set = HVAC_MODE_SETS.get(
self._config.get(CONF_HVAC_MODE_SET), {}
)
self._conf_hvac_mode_set = HVAC_MODE_SETS.get(self._config.get(CONF_HVAC_MODE_SET), {})
self._conf_hvac_mode_cooling_dp = self._config.get(CONF_HVAC_MODE_COOLING_DP)
self._conf_hvac_mode_cooling_set = HVAC_MODE_COOLING_SETS.get(self._config.get(CONF_HVAC_MODE_COOLING_SET), {})
self._conf_preset_dp = self._config.get(CONF_PRESET_DP)
self._conf_preset_set = PRESET_SETS.get(self._config.get(CONF_PRESET_SET), {})
self._conf_hvac_action_dp = self._config.get(CONF_HVAC_ACTION_DP)
self._conf_hvac_action_set = HVAC_ACTION_SETS.get(
self._config.get(CONF_HVAC_ACTION_SET), {}
)
self._conf_hvac_action_set = HVAC_ACTION_SETS.get(self._config.get(CONF_HVAC_ACTION_SET), {})
self._conf_eco_dp = self._config.get(CONF_ECO_DP)
self._conf_eco_value = self._config.get(CONF_ECO_VALUE, "ECO")
self._has_presets = self.has_config(CONF_ECO_DP) or self.has_config(
CONF_PRESET_DP
)
self._has_presets = self.has_config(CONF_ECO_DP) or self.has_config(CONF_PRESET_DP)
_LOGGER.debug("Initialized climate [%s]", self.name)

@property
Expand Down Expand Up @@ -208,10 +208,7 @@ def target_precision(self):
@property
def temperature_unit(self):
"""Return the unit of measurement used by the platform."""
if (
self._config.get(CONF_TEMPERATURE_UNIT, DEFAULT_TEMPERATURE_UNIT)
== TEMPERATURE_FAHRENHEIT
):
if self._config.get(CONF_TEMPERATURE_UNIT, DEFAULT_TEMPERATURE_UNIT) == TEMPERATURE_FAHRENHEIT:
return UnitOfTemperature.FAHRENHEIT
return UnitOfTemperature.CELSIUS

Expand All @@ -225,7 +222,9 @@ def hvac_modes(self):
"""Return the list of available operation modes."""
if not self.has_config(CONF_HVAC_MODE_DP):
return None
return list(self._conf_hvac_mode_set) + [HVAC_MODE_OFF]
elif not self.has_config(CONF_HVAC_MODE_COOLING_DP):
return list(self._conf_hvac_mode_set) + [HVAC_MODE_OFF]
return list(self._conf_hvac_mode_set) + [HVAC_MODE_OFF, HVAC_MODE_COOL]

@property
def hvac_action(self):
Expand All @@ -235,20 +234,14 @@ def hvac_action(self):
"""
if self._config.get(CONF_HEURISTIC_ACTION, False):
if self._hvac_mode == HVAC_MODE_HEAT:
if self._current_temperature < (
self._target_temperature - self._precision
):
if self._current_temperature < (self._target_temperature - self._precision):
self._hvac_action = CURRENT_HVAC_HEAT
if self._current_temperature == (
self._target_temperature - self._precision
):
if self._current_temperature == (self._target_temperature - self._precision):
if self._hvac_action == CURRENT_HVAC_HEAT:
self._hvac_action = CURRENT_HVAC_HEAT
if self._hvac_action == CURRENT_HVAC_IDLE:
self._hvac_action = CURRENT_HVAC_IDLE
if (
self._current_temperature + self._precision
) > self._target_temperature:
if (self._current_temperature + self._precision) > self._target_temperature:
self._hvac_action = CURRENT_HVAC_IDLE
return self._hvac_action
return self._hvac_action
Expand Down Expand Up @@ -297,9 +290,7 @@ async def async_set_temperature(self, **kwargs):
"""Set new target temperature."""
if ATTR_TEMPERATURE in kwargs and self.has_config(CONF_TARGET_TEMPERATURE_DP):
temperature = round(kwargs[ATTR_TEMPERATURE] / self._target_precision)
await self._device.set_dp(
temperature, self._config[CONF_TARGET_TEMPERATURE_DP]
)
await self._device.set_dp(temperature, self._config[CONF_TARGET_TEMPERATURE_DP])

def set_fan_mode(self, fan_mode):
"""Set new target fan mode."""
Expand All @@ -314,9 +305,13 @@ async def async_set_hvac_mode(self, hvac_mode):
await self._device.set_dp(True, self._dp_id)
# Some thermostats need a small wait before sending another update
await asyncio.sleep(MODE_WAIT)
await self._device.set_dp(
self._conf_hvac_mode_set[hvac_mode], self._conf_hvac_mode_dp
)
if self.has_config(CONF_HVAC_MODE_COOLING_DP):
if hvac_mode in [HVAC_MODE_HEAT, HVAC_MODE_COOL]:
self._device.set_dp(self._conf_hvac_mode_set[HVAC_MODE_HEAT], self._conf_hvac_mode_dp)
await asyncio.sleep(MODE_WAIT)
await self._device.set_dp(self._conf_hvac_mode_cooling_set[hvac_mode], self._conf_hvac_mode_cooling_dp)
else:
await self._device.set_dp(self._conf_hvac_mode_set[hvac_mode], self._conf_hvac_mode_dp)

async def async_turn_on(self) -> None:
"""Turn the entity on."""
Expand All @@ -331,9 +326,7 @@ async def async_set_preset_mode(self, preset_mode):
if preset_mode == PRESET_ECO:
await self._device.set_dp(self._conf_eco_value, self._conf_eco_dp)
return
await self._device.set_dp(
self._conf_preset_set[preset_mode], self._conf_preset_dp
)
await self._device.set_dp(self._conf_preset_set[preset_mode], self._conf_preset_dp)

@property
def min_temp(self):
Expand Down Expand Up @@ -362,20 +355,13 @@ def status_updated(self):
self._state = self.dps(self._dp_id)

if self.has_config(CONF_TARGET_TEMPERATURE_DP):
self._target_temperature = (
self.dps_conf(CONF_TARGET_TEMPERATURE_DP) * self._target_precision
)
self._target_temperature = self.dps_conf(CONF_TARGET_TEMPERATURE_DP) * self._target_precision

if self.has_config(CONF_CURRENT_TEMPERATURE_DP):
self._current_temperature = (
self.dps_conf(CONF_CURRENT_TEMPERATURE_DP) * self._precision
)
self._current_temperature = self.dps_conf(CONF_CURRENT_TEMPERATURE_DP) * self._precision

if self._has_presets:
if (
self.has_config(CONF_ECO_DP)
and self.dps_conf(CONF_ECO_DP) == self._conf_eco_value
):
if self.has_config(CONF_ECO_DP) and self.dps_conf(CONF_ECO_DP) == self._conf_eco_value:
self._preset_mode = PRESET_ECO
else:
for preset, value in self._conf_preset_set.items(): # todo remove
Expand All @@ -392,6 +378,11 @@ def status_updated(self):
else:
for mode, value in self._conf_hvac_mode_set.items():
if self.dps_conf(CONF_HVAC_MODE_DP) == value:
if self.has_config(CONF_HVAC_MODE_COOLING_DP) and mode == HVAC_MODE_HEAT:
for mode, value in self._conf_hvac_mode_cooling_set.items():
if self.dps_conf(CONF_HVAC_MODE_COOLING_DP) == value:
self._hvac_mode = mode
break
self._hvac_mode = mode
break
else:
Expand All @@ -401,6 +392,13 @@ def status_updated(self):
# Update the current action
for action, value in self._conf_hvac_action_set.items():
if self.dps_conf(CONF_HVAC_ACTION_DP) == value:
if (
self.has_config(CONF_HVAC_MODE_COOLING_DP)
and action == CURRENT_HVAC_HEAT
and self.dps_conf(CONF_HVAC_MODE_COOLING_DP) == HVAC_MODE_COOL
):
self._hvac_action = CURRENT_HVAC_COOL

self._hvac_action = action


Expand Down
2 changes: 2 additions & 0 deletions custom_components/localtuya/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
CONF_TARGET_PRECISION = "target_precision"
CONF_HVAC_MODE_DP = "hvac_mode_dp"
CONF_HVAC_MODE_SET = "hvac_mode_set"
CONF_HVAC_MODE_COOLING_DP = "hvac_mode_cooling_dp"
CONF_HVAC_MODE_COOLING_SET = "hvac_mode_cooling_set"
CONF_PRESET_DP = "preset_dp"
CONF_PRESET_SET = "preset_set"
CONF_HEURISTIC_ACTION = "heuristic_action"
Expand Down
4 changes: 3 additions & 1 deletion custom_components/localtuya/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@
"temperature_unit": "Temperature Unit (optional)",
"hvac_mode_dp": "HVAC Mode DP (optional)",
"hvac_mode_set": "HVAC Mode Set (optional)",
"hvac_mode_cooling_dp": "HVAC Mode Cooling DP (optional)",
"hvac_mode_coooling_set": "HVAC Mode Cooling Set (optional)",
"hvac_action_dp": "HVAC Current Action DP (optional)",
"hvac_action_set": "HVAC Current Action Set (optional)",
"preset_dp": "Presets DP (optional)",
Expand All @@ -136,4 +138,4 @@
}
},
"title": "LocalTuya"
}
}
4 changes: 3 additions & 1 deletion custom_components/localtuya/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@
"temperature_unit": "Temperature Unit (optional)",
"hvac_mode_dp": "HVAC Mode DP (optional)",
"hvac_mode_set": "HVAC Mode Set (optional)",
"hvac_mode_cooling_dp": "HVAC Mode Cooling DP (optional)",
"hvac_mode_coooling_set": "HVAC Mode Cooling Set (optional)",
"hvac_action_dp": "HVAC Current Action DP (optional)",
"hvac_action_set": "HVAC Current Action Set (optional)",
"preset_dp": "Presets DP (optional)",
Expand Down Expand Up @@ -223,4 +225,4 @@
}
},
"title": "LocalTuya"
}
}
4 changes: 3 additions & 1 deletion custom_components/localtuya/translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
"fan_speed_min": "Velocità del ventilatore minima",
"fan_speed_max": "Velocità del ventilatore massima",
"fan_speed_ordered_list": "Elenco delle modalità di velocità del ventilatore (sovrascrive velocità min/max)",
"fan_direction":"DP di direzione del ventilatore",
"fan_direction": "DP di direzione del ventilatore",
"fan_direction_forward": "Stringa del DP per avanti",
"fan_direction_reverse": "Stringa del DP per indietro",
"current_temperature_dp": "Temperatura attuale",
Expand All @@ -177,6 +177,8 @@
"temperature_unit": "Unità di temperatura (opzionale)",
"hvac_mode_dp": "Modalità HVAC attuale (opzionale)",
"hvac_mode_set": "Impostazione modalità HVAC (opzionale)",
"hvac_mode_cooling_dp": "Modalità HVAC corrente di raffreddamento (opzionale)",
"hvac_mode_coooling_set": "Impostazione del raffreddamento in modalità HVAC (opzionale)",
"hvac_action_dp": "Azione HVAC attuale (opzionale)",
"hvac_action_set": "Impostazione azione HVAC (opzionale)",
"preset_dp": "Preset DP (opzionale)",
Expand Down
4 changes: 3 additions & 1 deletion custom_components/localtuya/translations/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
"fan_speed_min": "Velocidade mínima do ventilador inteiro",
"fan_speed_max": "Velocidade máxima do ventilador inteiro",
"fan_speed_ordered_list": "Lista de modos de velocidade do ventilador (substitui a velocidade min/max)",
"fan_direction":"Direção do ventilador dps",
"fan_direction": "Direção do ventilador dps",
"fan_direction_forward": "Seqüência de dps para frente",
"fan_direction_reverse": "String dps reversa",
"current_temperature_dp": "Temperatura atual",
Expand All @@ -177,6 +177,8 @@
"temperature_unit": "Unidade de Temperatura (opcional)",
"hvac_mode_dp": "Modo HVAC DP (opcional)",
"hvac_mode_set": "Conjunto de modo HVAC (opcional)",
"hvac_mode_cooling_dp": "Conjunto de arrefecimento do modo AVAC (opcional)",
"hvac_mode_coooling_set": "HVAC Mode Cooling Set (optional)",
"hvac_action_dp": "Ação atual de HVAC DP (opcional)",
"hvac_action_set": "Conjunto de ação atual HVAC (opcional)",
"preset_dp": "Predefinições DP (opcional)",
Expand Down