Forráskód Böngészése

Add some basic redirection capability.

Also changed the error message for out of range values to not include "Target", as this might be misleading for some DPS.
Jason Rumney 4 éve
szülő
commit
be63972f82

+ 16 - 2
custom_components/tuya_local/helpers/device_config.py

@@ -319,6 +319,7 @@ class TuyaDpsConfig:
             scale = mapping.get("scale", 1)
             if not isinstance(scale, (int, float)):
                 scale = 1
+            redirect = mapping.get("value-redirect")
             replaced = "value" in mapping
             result = mapping.get("value", result)
             cond = self._active_condition(mapping, device)
@@ -328,12 +329,19 @@ class TuyaDpsConfig:
                 replaced = replaced or "value" in cond
                 result = cond.get("value", result)
                 scale = cond.get("scale", scale)
+                redirect = cond.get("value-redirect", redirect)
+
                 if "mapping" in cond:
                     for m in cond["mapping"]:
                         if str(m.get("dps_val")) == str(result):
                             replaced = "value" in m
                             result = m.get("value", result)
 
+            if redirect is not None:
+                _LOGGER.debug(f"Redirecting {self.name} to {redirect}")
+                r_dps = self._entity.find_dps(redirect)
+                return r_dps.get_value(device)
+
             if scale != 1 and isinstance(result, (int, float)):
                 result = result / scale
                 replaced = True
@@ -384,6 +392,7 @@ class TuyaDpsConfig:
         if mapping is not None:
             replaced = False
             scale = mapping.get("scale", 1)
+            redirect = mapping.get("value-redirect")
             if not isinstance(scale, (int, float)):
                 scale = 1
             step = mapping.get("step")
@@ -400,6 +409,12 @@ class TuyaDpsConfig:
                     dps_map.update(c_dps.get_values_to_set(device, cond["dps_val"]))
                 scale = cond.get("scale", scale)
                 step = cond.get("step", step)
+                redirect = cond.get("value-redirect", redirect)
+
+            if redirect is not None:
+                _LOGGER.debug(f"Redirecting {self.name} to {redirect}")
+                r_dps = self._entity.find_dps(redirect)
+                return r_dps.get_values_to_set(device, value)
 
             if scale != 1 and isinstance(result, (int, float)):
                 _LOGGER.debug(f"Scaling {result} by {scale}")
@@ -426,8 +441,7 @@ class TuyaDpsConfig:
             maximum = range["max"]
             if result < minimum or result > maximum:
                 raise ValueError(
-                    f"Target {self.name} ({value}) must be between "
-                    f"{minimum} and {maximum}"
+                    f"{self.name} ({value}) must be between " f"{minimum} and {maximum}"
                 )
 
         if self.type is int:

+ 2 - 2
tests/devices/test_andersson_gsh_heater.py

@@ -116,12 +116,12 @@ class TestAnderssonGSHHeater(IsolatedAsyncioTestCase):
 
     async def test_set_target_temperature_fails_outside_valid_range(self):
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(4\\) must be between 5 and 35"
+            ValueError, "temperature \\(4\\) must be between 5 and 35"
         ):
             await self.subject.async_set_target_temperature(4)
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(36\\) must be between 5 and 35"
+            ValueError, "temperature \\(36\\) must be between 5 and 35"
         ):
             await self.subject.async_set_target_temperature(36)
 

+ 2 - 2
tests/devices/test_eurom_600_heater.py

@@ -103,12 +103,12 @@ class TestEurom600Heater(IsolatedAsyncioTestCase):
 
     async def test_set_target_temperature_fails_outside_valid_range(self):
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(14\\) must be between 15 and 35"
+            ValueError, "temperature \\(14\\) must be between 15 and 35"
         ):
             await self.subject.async_set_target_temperature(14)
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(36\\) must be between 15 and 35"
+            ValueError, "temperature \\(36\\) must be between 15 and 35"
         ):
             await self.subject.async_set_target_temperature(36)
 

+ 2 - 2
tests/devices/test_gardenpac_heatpump.py

@@ -124,12 +124,12 @@ class TestGardenPACPoolHeatpump(IsolatedAsyncioTestCase):
 
     async def test_set_target_temperature_fails_outside_valid_range(self):
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(14\\) must be between 18 and 45"
+            ValueError, "temperature \\(14\\) must be between 18 and 45"
         ):
             await self.subject.async_set_target_temperature(14)
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(46\\) must be between 18 and 45"
+            ValueError, "temperature \\(46\\) must be between 18 and 45"
         ):
             await self.subject.async_set_target_temperature(46)
 

+ 0 - 8
tests/devices/test_goldair_dehumidifier.py

@@ -583,14 +583,6 @@ class TestGoldairDehumidifier(IsolatedAsyncioTestCase):
         # ):
         #     await self.subject.async_set_fan_mode(FAN_HIGH)
 
-    @skip("Redirection not supported yet")
-    def test_tank_full_or_missing(self):
-        self.dps[ERROR_DPS] = None
-        self.assertEqual(self.subject.tank_full_or_missing, False)
-
-        self.dps[ERROR_DPS] = 8
-        self.assertEqual(self.subject.tank_full_or_missing, True)
-
     def test_device_state_attributes(self):
         self.dps[ERROR_DPS] = None
         self.dps[DEFROST_DPS] = False

+ 2 - 2
tests/devices/test_goldair_geco_heater.py

@@ -123,12 +123,12 @@ class TestGoldairGECOHeater(IsolatedAsyncioTestCase):
 
     async def test_set_target_temperature_fails_outside_valid_range(self):
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(14\\) must be between 15 and 35"
+            ValueError, "temperature \\(14\\) must be between 15 and 35"
         ):
             await self.subject.async_set_target_temperature(14)
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(36\\) must be between 15 and 35"
+            ValueError, "temperature \\(36\\) must be between 15 and 35"
         ):
             await self.subject.async_set_target_temperature(36)
 

+ 2 - 2
tests/devices/test_goldair_gpcv_heater.py

@@ -137,12 +137,12 @@ class TestGoldairGPCVHeater(IsolatedAsyncioTestCase):
 
     async def test_set_target_temperature_fails_outside_valid_range(self):
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(14\\) must be between 15 and 35"
+            ValueError, "temperature \\(14\\) must be between 15 and 35"
         ):
             await self.subject.async_set_target_temperature(14)
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(36\\) must be between 15 and 35"
+            ValueError, "temperature \\(36\\) must be between 15 and 35"
         ):
             await self.subject.async_set_target_temperature(36)
 

+ 4 - 8
tests/devices/test_goldair_gpph_heater.py

@@ -112,7 +112,6 @@ class TestGoldairHeater(IsolatedAsyncioTestCase):
         self.dps[PRESET_DPS] = "C"
         self.assertEqual(self.subject.target_temperature, 25)
 
-    @skip("Conditional redirection not supported.")
     def test_target_temperature_in_eco_and_af_modes(self):
         self.dps[TEMPERATURE_DPS] = 25
         self.dps[ECOTEMP_DPS] = 15
@@ -182,7 +181,6 @@ class TestGoldairHeater(IsolatedAsyncioTestCase):
         ):
             await self.subject.async_set_target_temperature(25)
 
-    @skip("Redirection not yet supported")
     async def test_set_target_temperature_in_eco_mode(self):
         self.dps[PRESET_DPS] = "ECO"
 
@@ -202,12 +200,12 @@ class TestGoldairHeater(IsolatedAsyncioTestCase):
         self.dps[PRESET_DPS] = "C"
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(4\\) must be between 5 and 35"
+            ValueError, "temperature \\(4\\) must be between 5 and 35"
         ):
             await self.subject.async_set_target_temperature(4)
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(36\\) must be between 5 and 35"
+            ValueError, "temperature \\(36\\) must be between 5 and 35"
         ):
             await self.subject.async_set_target_temperature(36)
 
@@ -215,12 +213,12 @@ class TestGoldairHeater(IsolatedAsyncioTestCase):
         self.dps[PRESET_DPS] = "ECO"
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(4\\) must be between 5 and 21"
+            ValueError, "eco_temperature \\(4\\) must be between 5 and 21"
         ):
             await self.subject.async_set_target_temperature(4)
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(22\\) must be between 5 and 21"
+            ValueError, "eco_temperature \\(22\\) must be between 5 and 21"
         ):
             await self.subject.async_set_target_temperature(22)
 
@@ -298,7 +296,6 @@ class TestGoldairHeater(IsolatedAsyncioTestCase):
         ):
             await self.subject.async_set_preset_mode("away")
 
-    @skip("Conditional redirection not yet supported")
     def test_power_level_returns_user_power_level(self):
         self.dps[SWING_DPS] = "user"
 
@@ -336,7 +333,6 @@ class TestGoldairHeater(IsolatedAsyncioTestCase):
         ):
             await self.subject.async_set_swing_mode("Stop")
 
-    @skip("Conditional redirection not supported yet")
     async def test_set_swing_mode_to_auto(self):
         async with assert_device_properties_set(
             self.subject._device,

+ 2 - 2
tests/devices/test_kogan_heater.py

@@ -136,12 +136,12 @@ class TestGoldairKoganHeater(IsolatedAsyncioTestCase):
 
     async def test_set_target_temperature_fails_outside_valid_range(self):
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(14\\) must be between 15 and 35"
+            ValueError, "temperature \\(14\\) must be between 15 and 35"
         ):
             await self.subject.async_set_target_temperature(14)
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(36\\) must be between 15 and 35"
+            ValueError, "temperature \\(36\\) must be between 15 and 35"
         ):
             await self.subject.async_set_target_temperature(36)
 

+ 2 - 2
tests/devices/test_purline_m100_heater.py

@@ -147,12 +147,12 @@ class TestPulineM100Heater(IsolatedAsyncioTestCase):
 
     async def test_set_target_temperature_fails_outside_valid_range(self):
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(4\\) must be between 15 and 35"
+            ValueError, "temperature \\(4\\) must be between 15 and 35"
         ):
             await self.subject.async_set_target_temperature(4)
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(36\\) must be between 15 and 35"
+            ValueError, "temperature \\(36\\) must be between 15 and 35"
         ):
             await self.subject.async_set_target_temperature(36)
 

+ 2 - 2
tests/devices/test_remora_heatpump.py

@@ -117,12 +117,12 @@ class TestRemoraHeatpump(IsolatedAsyncioTestCase):
 
     async def test_set_target_temperature_fails_outside_valid_range(self):
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(4\\) must be between 5 and 40"
+            ValueError, "temperature \\(4\\) must be between 5 and 40"
         ):
             await self.subject.async_set_target_temperature(4)
 
         with self.assertRaisesRegex(
-            ValueError, "Target temperature \\(41\\) must be between 5 and 40"
+            ValueError, "temperature \\(41\\) must be between 5 and 40"
         ):
             await self.subject.async_set_target_temperature(41)