|
@@ -5,17 +5,26 @@ import logging
|
|
|
|
|
|
|
|
from homeassistant.components.climate import ClimateEntity
|
|
from homeassistant.components.climate import ClimateEntity
|
|
|
from homeassistant.components.climate.const import (
|
|
from homeassistant.components.climate.const import (
|
|
|
|
|
+ ATTR_CURRENT_HUMIDITY,
|
|
|
|
|
+ ATTR_CURRENT_TEMPERATURE,
|
|
|
|
|
+ ATTR_FAN_MODE,
|
|
|
|
|
+ ATTR_HUMIDITY,
|
|
|
ATTR_PRESET_MODE,
|
|
ATTR_PRESET_MODE,
|
|
|
|
|
+ ATTR_SWING_MODE,
|
|
|
|
|
+ ATTR_TARGET_TEMP_HIGH,
|
|
|
|
|
+ ATTR_TARGET_TEMP_LOW,
|
|
|
DEFAULT_MAX_HUMIDITY,
|
|
DEFAULT_MAX_HUMIDITY,
|
|
|
DEFAULT_MAX_TEMP,
|
|
DEFAULT_MAX_TEMP,
|
|
|
DEFAULT_MIN_HUMIDITY,
|
|
DEFAULT_MIN_HUMIDITY,
|
|
|
DEFAULT_MIN_TEMP,
|
|
DEFAULT_MIN_TEMP,
|
|
|
- HVAC_MODE_HEAT,
|
|
|
|
|
|
|
+ HVAC_MODE_AUTO,
|
|
|
|
|
+ HVAC_MODE_OFF,
|
|
|
SUPPORT_FAN_MODE,
|
|
SUPPORT_FAN_MODE,
|
|
|
SUPPORT_PRESET_MODE,
|
|
SUPPORT_PRESET_MODE,
|
|
|
SUPPORT_SWING_MODE,
|
|
SUPPORT_SWING_MODE,
|
|
|
SUPPORT_TARGET_HUMIDITY,
|
|
SUPPORT_TARGET_HUMIDITY,
|
|
|
SUPPORT_TARGET_TEMPERATURE,
|
|
SUPPORT_TARGET_TEMPERATURE,
|
|
|
|
|
+ SUPPORT_TARGET_TEMPERATURE_RANGE,
|
|
|
)
|
|
)
|
|
|
from homeassistant.const import (
|
|
from homeassistant.const import (
|
|
|
ATTR_TEMPERATURE,
|
|
ATTR_TEMPERATURE,
|
|
@@ -46,6 +55,8 @@ class TuyaLocalClimate(ClimateEntity):
|
|
|
self._support_flags = 0
|
|
self._support_flags = 0
|
|
|
self._current_temperature_dps = None
|
|
self._current_temperature_dps = None
|
|
|
self._temperature_dps = None
|
|
self._temperature_dps = None
|
|
|
|
|
+ self._temp_high_dps = None
|
|
|
|
|
+ self._temp_low_dps = None
|
|
|
self._current_humidity_dps = None
|
|
self._current_humidity_dps = None
|
|
|
self._humidity_dps = None
|
|
self._humidity_dps = None
|
|
|
self._preset_mode_dps = None
|
|
self._preset_mode_dps = None
|
|
@@ -59,23 +70,26 @@ class TuyaLocalClimate(ClimateEntity):
|
|
|
for d in config.dps():
|
|
for d in config.dps():
|
|
|
if d.name == "hvac_mode":
|
|
if d.name == "hvac_mode":
|
|
|
self._hvac_mode_dps = d
|
|
self._hvac_mode_dps = d
|
|
|
- elif d.name == "temperature":
|
|
|
|
|
|
|
+ elif d.name == ATTR_TEMPERATURE:
|
|
|
self._temperature_dps = d
|
|
self._temperature_dps = d
|
|
|
- self._support_flags |= SUPPORT_TARGET_TEMPERATURE
|
|
|
|
|
- elif d.name == "current_temperature":
|
|
|
|
|
|
|
+ elif d.name == ATTR_TARGET_TEMP_HIGH:
|
|
|
|
|
+ self._temp_high_dps = d
|
|
|
|
|
+ elif d.name == ATTR_TARGET_TEMP_LOW:
|
|
|
|
|
+ self._temp_low_dps = d
|
|
|
|
|
+ elif d.name == ATTR_CURRENT_TEMPERATURE:
|
|
|
self._current_temperature_dps = d
|
|
self._current_temperature_dps = d
|
|
|
- elif d.name == "humidity":
|
|
|
|
|
|
|
+ elif d.name == ATTR_HUMIDITY:
|
|
|
self._humidity_dps = d
|
|
self._humidity_dps = d
|
|
|
self._support_flags |= SUPPORT_TARGET_HUMIDITY
|
|
self._support_flags |= SUPPORT_TARGET_HUMIDITY
|
|
|
- elif d.name == "current_humidity":
|
|
|
|
|
|
|
+ elif d.name == ATTR_CURRENT_HUMIDITY:
|
|
|
self._current_humidity_dps = d
|
|
self._current_humidity_dps = d
|
|
|
- elif d.name == "preset_mode":
|
|
|
|
|
|
|
+ elif d.name == ATTR_PRESET_MODE:
|
|
|
self._preset_mode_dps = d
|
|
self._preset_mode_dps = d
|
|
|
self._support_flags |= SUPPORT_PRESET_MODE
|
|
self._support_flags |= SUPPORT_PRESET_MODE
|
|
|
- elif d.name == "swing_mode":
|
|
|
|
|
|
|
+ elif d.name == ATTR_SWING_MODE:
|
|
|
self._swing_mode_dps = d
|
|
self._swing_mode_dps = d
|
|
|
self._support_flags |= SUPPORT_SWING_MODE
|
|
self._support_flags |= SUPPORT_SWING_MODE
|
|
|
- elif d.name == "fan_mode":
|
|
|
|
|
|
|
+ elif d.name == ATTR_FAN_MODE:
|
|
|
self._fan_mode_dps = d
|
|
self._fan_mode_dps = d
|
|
|
self._support_flags |= SUPPORT_FAN_MODE
|
|
self._support_flags |= SUPPORT_FAN_MODE
|
|
|
elif d.name == "temperature_unit":
|
|
elif d.name == "temperature_unit":
|
|
@@ -83,6 +97,11 @@ class TuyaLocalClimate(ClimateEntity):
|
|
|
elif not d.hidden:
|
|
elif not d.hidden:
|
|
|
self._attr_dps.append(d)
|
|
self._attr_dps.append(d)
|
|
|
|
|
|
|
|
|
|
+ if self._temp_high_dps is not None and self._temp_low_dps is not None:
|
|
|
|
|
+ self._support_flags |= SUPPORT_TARGET_TEMPERATURE_RANGE
|
|
|
|
|
+ elif self._temperature_dps is not None:
|
|
|
|
|
+ self._support_flags |= SUPPORT_TARGET_TEMPERATURE
|
|
|
|
|
+
|
|
|
@property
|
|
@property
|
|
|
def supported_features(self):
|
|
def supported_features(self):
|
|
|
"""Return the features supported by this climate device."""
|
|
"""Return the features supported by this climate device."""
|
|
@@ -116,10 +135,10 @@ class TuyaLocalClimate(ClimateEntity):
|
|
|
@property
|
|
@property
|
|
|
def icon(self):
|
|
def icon(self):
|
|
|
"""Return the icon to use in the frontend for this device."""
|
|
"""Return the icon to use in the frontend for this device."""
|
|
|
- if self.hvac_mode == HVAC_MODE_HEAT:
|
|
|
|
|
- return "mdi:radiator"
|
|
|
|
|
|
|
+ if self.hvac_mode == HVAC_MODE_OFF:
|
|
|
|
|
+ return "mdi:hvac-off"
|
|
|
else:
|
|
else:
|
|
|
- return "mdi:radiator-disabled"
|
|
|
|
|
|
|
+ return "mdi:hvac"
|
|
|
|
|
|
|
|
@property
|
|
@property
|
|
|
def temperature_unit(self):
|
|
def temperature_unit(self):
|
|
@@ -142,6 +161,20 @@ class TuyaLocalClimate(ClimateEntity):
|
|
|
raise NotImplementedError()
|
|
raise NotImplementedError()
|
|
|
return self._temperature_dps.get_value(self._device)
|
|
return self._temperature_dps.get_value(self._device)
|
|
|
|
|
|
|
|
|
|
+ @property
|
|
|
|
|
+ def target_temperature_high(self):
|
|
|
|
|
+ """Return the currently set high target temperature."""
|
|
|
|
|
+ if self._temp_high_dps is None:
|
|
|
|
|
+ raise NotImplementedError()
|
|
|
|
|
+ return self._temp_high_dps.get_value(self._device)
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def target_temperature_low(self):
|
|
|
|
|
+ """Return the currently set low target temperature."""
|
|
|
|
|
+ if self._temp_low_dps is None:
|
|
|
|
|
+ raise NotImplementedError()
|
|
|
|
|
+ return self._temp_low_dps.get_value(self._device)
|
|
|
|
|
+
|
|
|
@property
|
|
@property
|
|
|
def target_temperature_step(self):
|
|
def target_temperature_step(self):
|
|
|
"""Return the supported step of target temperature."""
|
|
"""Return the supported step of target temperature."""
|
|
@@ -171,15 +204,24 @@ class TuyaLocalClimate(ClimateEntity):
|
|
|
await self.async_set_preset_mode(kwargs.get(ATTR_PRESET_MODE))
|
|
await self.async_set_preset_mode(kwargs.get(ATTR_PRESET_MODE))
|
|
|
if kwargs.get(ATTR_TEMPERATURE) is not None:
|
|
if kwargs.get(ATTR_TEMPERATURE) is not None:
|
|
|
await self.async_set_target_temperature(kwargs.get(ATTR_TEMPERATURE))
|
|
await self.async_set_target_temperature(kwargs.get(ATTR_TEMPERATURE))
|
|
|
|
|
+ high = kwargs.get(ATTR_TARGET_TEMP_HIGH)
|
|
|
|
|
+ low = kwargs.get(ATTR_TARGET_TEMP_LOW)
|
|
|
|
|
+ if high is not None or low is not None:
|
|
|
|
|
+ await self.async_set_target_temperature_range(low, high)
|
|
|
|
|
|
|
|
async def async_set_target_temperature(self, target_temperature):
|
|
async def async_set_target_temperature(self, target_temperature):
|
|
|
if self._temperature_dps is None:
|
|
if self._temperature_dps is None:
|
|
|
raise NotImplementedError()
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
- target_temperature = int(round(target_temperature))
|
|
|
|
|
-
|
|
|
|
|
await self._temperature_dps.async_set_value(self._device, target_temperature)
|
|
await self._temperature_dps.async_set_value(self._device, target_temperature)
|
|
|
|
|
|
|
|
|
|
+ async def async_set_target_temperature_range(self, low, high):
|
|
|
|
|
+ """Set the target temperature range."""
|
|
|
|
|
+ if low is not None and self._temp_low_dps is not None:
|
|
|
|
|
+ await self._temp_low_dps.async_set_value(self._device, low)
|
|
|
|
|
+ if high is not None and self._temp_high_dps is not None:
|
|
|
|
|
+ await self._temp_high_dps.async_set_value(self._device, high)
|
|
|
|
|
+
|
|
|
@property
|
|
@property
|
|
|
def current_temperature(self):
|
|
def current_temperature(self):
|
|
|
"""Return the current measured temperature."""
|
|
"""Return the current measured temperature."""
|
|
@@ -229,7 +271,7 @@ class TuyaLocalClimate(ClimateEntity):
|
|
|
def hvac_mode(self):
|
|
def hvac_mode(self):
|
|
|
"""Return current HVAC mode."""
|
|
"""Return current HVAC mode."""
|
|
|
if self._hvac_mode_dps is None:
|
|
if self._hvac_mode_dps is None:
|
|
|
- raise NotImplementedError()
|
|
|
|
|
|
|
+ return HVAC_MODE_AUTO
|
|
|
hvac_mode = self._hvac_mode_dps.get_value(self._device)
|
|
hvac_mode = self._hvac_mode_dps.get_value(self._device)
|
|
|
return STATE_UNAVAILABLE if hvac_mode is None else hvac_mode
|
|
return STATE_UNAVAILABLE if hvac_mode is None else hvac_mode
|
|
|
|
|
|
|
@@ -237,7 +279,7 @@ class TuyaLocalClimate(ClimateEntity):
|
|
|
def hvac_modes(self):
|
|
def hvac_modes(self):
|
|
|
"""Return available HVAC modes."""
|
|
"""Return available HVAC modes."""
|
|
|
if self._hvac_mode_dps is None:
|
|
if self._hvac_mode_dps is None:
|
|
|
- return None
|
|
|
|
|
|
|
+ return []
|
|
|
else:
|
|
else:
|
|
|
return self._hvac_mode_dps.values
|
|
return self._hvac_mode_dps.values
|
|
|
|
|
|