فهرست منبع

water_heater: add away_mode support.

Some tuya devices include away or anti-frost in the operation_modes.
Cater to both this and the separate boolean toggle HA is expecting.

- Add device config docs for water_heater.
- Make `default` a property
Jason Rumney 3 سال پیش
والد
کامیت
ae7e4ebea5

+ 18 - 1
custom_components/tuya_local/devices/README.md

@@ -618,6 +618,23 @@ Humidifer can also cover dehumidifiers (use class to specify which).
 
 ### siren
 - **tone** (required, mapping of strings): a dp to report and control the siren tone. As this is used to turn on and off the siren, it is required. If this does not fit your siren, the underlying implementation will need to be modified.
-The value "off" will be used for turning off the siren, and will be filtered from the list of available tones.
+The value "off" will be used for turning off the siren, and will be filtered from the list of available tones. One value must be marked as `default: true` so that the `turn_on` service with no commands works.
 - **volume** (optional, float in range 0.0-1.0): a dp to control the volume of the siren (probably needs a scale and step applied, since Tuya devices will probably use an integer, or strings with fixed values).
 - **duration** (optional, integer): a dp to control how long the siren will sound for.
+
+### water_heater
+- **current_temperature** (optional, number): a dp that reports the current water temperature.
+
+- **operation_mode** (optional, mapping of strings): a dp to report and control the operation mode of the water heater.  If `away` is one of the modes, another mode must be marked as `default: true` to that the `away_mode_off` service knows which mode to switch out of away mode to.
+
+- **temperature** (optional, number): a dp to control the target water temperature of the water heater. A unit may be specified as an attribute if the `temperature_unit` dp is not available, otherwise the default of HA's current setting will be used.
+
+- **temperature_unit** (optional, string): a dp that reports the unit the device is configured for.
+    Values should be mapped to "C" or "F" (case sensitive) - often the device will use a boolean or	lower case for this
+
+- **min_temperature** (optional, number): a dp that reports the minimum temperature the water heater can be set to, in case this is not a fixed value.
+
+- **max_temperature** (optional, number): a dp that reports the maximum temperature the water heater can be set to, in case this is not a fixed value. 
+
+- **away_mode** (optional, boolean): a dp to control whether the water heater is in away mode.
+

+ 1 - 0
custom_components/tuya_local/helpers/device_config.py

@@ -474,6 +474,7 @@ class TuyaDpsConfig:
         _LOGGER.debug("%s values: %s", self.name, val)
         return list(set(val)) if val else []
 
+    @property
     def default(self):
         """Return the default value for a dp."""
         if "mapping" not in self._config.keys():

+ 1 - 1
custom_components/tuya_local/siren.py

@@ -50,7 +50,7 @@ class TuyaLocalSiren(TuyaLocalEntity, SirenEntity):
             self._attr_available_tones = [
                 x for x in self._tone_dp.values(device) if x != "off"
             ]
-            self._default_tone = self._tone_dp.default()
+            self._default_tone = self._tone_dp.default
 
         if self._volume_dp:
             support |= SirenEntityFeature.VOLUME_SET

+ 35 - 1
custom_components/tuya_local/water_heater.py

@@ -4,6 +4,7 @@ Setup for different kinds of Tuya water heater devices
 from homeassistant.components.water_heater import (
     ATTR_CURRENT_TEMPERATURE,
     ATTR_OPERATION_MODE,
+    ATTR_AWAY_MODE,
     WaterHeaterEntity,
     WaterHeaterEntityFeature,
 )
@@ -54,7 +55,8 @@ class TuyaLocalWaterHeater(TuyaLocalEntity, WaterHeaterEntity):
         self._unit_dps = dps_map.pop("temperature_unit", None)
         self._mintemp_dps = dps_map.pop("min_temperature", None)
         self._maxtemp_dps = dps_map.pop("max_temperature", None)
-        self._operation_mode_dps = dps_map.pop("operation_mode", None)
+        self._operation_mode_dps = dps_map.pop(ATTR_OPERATION_MODE, None)
+        self._away_mode_dps = dps_map.pop(ATTR_AWAY_MODE, None)
         self._init_end(dps_map)
         self._support_flags = 0
 
@@ -62,6 +64,11 @@ class TuyaLocalWaterHeater(TuyaLocalEntity, WaterHeaterEntity):
             self._support_flags |= WaterHeaterEntityFeature.OPERATION_MODE
         if self._temperature_dps and not self._temperature_dps.readonly:
             self._support_flags |= WaterHeaterEntityFeature.TARGET_TEMPERATURE
+        if self._away_mode_dps or (
+            self._operation_mode_dps
+            and "away" in self._operation_mode_dps.values(device)
+        ):
+            self._support_flags |= WaterHeaterEntityFeature.AWAY_MODE
 
     @property
     def supported_features(self):
@@ -108,6 +115,15 @@ class TuyaLocalWaterHeater(TuyaLocalEntity, WaterHeaterEntity):
         else:
             return self._operation_mode_dps.values(self._device)
 
+    @property
+    def is_away_mode_on(self):
+        if self._away_mode_dps:
+            return self._away_mode_dps.get_value(self._device)
+        elif self._operation_mode_dps and "away" in self._operation_mode_dps.values(
+            self._device
+        ):
+            return self.current_operation == "away"
+
     @property
     def current_temperature(self):
         """Return the current temperature."""
@@ -150,6 +166,24 @@ class TuyaLocalWaterHeater(TuyaLocalEntity, WaterHeaterEntity):
             raise NotImplementedError()
         await self._operation_mode_dps.async_set_value(self._device, operation_mode)
 
+    async def async_turn_away_mode_on(self):
+        """Turn away mode on"""
+        if self._away_mode_dps:
+            await self._away_mode_dps.async_set_value(self._device, True)
+        else if self._operation_mode_dps and "away" in self._operation_mode_dps.values(self._device):
+            await self.async_set_operation_mode("away")
+        else:
+            raise NotImplementedError()
+
+    async def async_turn_away_mode_off(self):
+        """Turn away mode off"""
+        if self._away_mode_dps:
+            await self._away_mode_dps.async_set_value(self._device, False)
+        else if self._operation_mode_dps and "away" in self._operation_mode_dps.values(self._device):
+            # switch to the default mode
+            await self.async_set_operation_mode(self._operation_mode_dps.default)
+
+
     @property
     def min_temp(self):
         """Return the minimum supported target temperature."""

+ 1 - 0
tests/test_device_config.py

@@ -116,6 +116,7 @@ KNOWN_DPS = {
             "temperature_unit",
             "min_temperature",
             "max_temperature",
+            "away_mode",
         ],
     },
 }