فهرست منبع

fix(goldair_portable_airconditioner): flatten logic

Using conditions results in undesired side effects and has
limitations.
Instead, use available to select different mapping options.
value needs to be listed for all applicable options to appear
as availablein values, but can be overridden by value_redirect.

- Add tests for this logic in test_goldair_portable_airconditioner.py
- Simplify the helper a little by reusing  common logic.

Issue #3496
Jason Rumney 6 ماه پیش
والد
کامیت
185eabedb6

+ 17 - 18
custom_components/tuya_local/devices/goldair_portable_airconditioner.yaml

@@ -71,18 +71,17 @@ entities:
         mapping:
           - dps_val: "on"
             value: "on"
-            available: support_swing
-            constraint: support_only_hswing
-            conditions:
-              - dps_val: true
-                value_redirect: swing_real_horizontal_mode
+            available: support_vswing
           - dps_val: "off"
+            available: support_vswing
             value: "off"
-            available: support_swing
-            constraint: support_only_hswing
-            conditions:
-              - dps_val: true
-                value_redirect: swing_real_horizontal_mode
+          - dps_val: "on"
+            available: support_only_hswing
+            value: "on"
+            value_redirect: swing_horizontal_only
+          - available: support_only_hswing
+            value: "off"
+            value_redirect: swing_horizontal_only
       - id: 107
         type: integer
         optional: true
@@ -106,13 +105,6 @@ entities:
           - dps_val: 1
             value: true
           - value: false
-      - id: 109
-        type: bitfield
-        name: support_hswing
-        mapping:
-          - dps_val: 2
-            value: true
-          - value: false
       - id: 109
         type: bitfield
         name: support_only_hswing
@@ -120,6 +112,13 @@ entities:
           - dps_val: 1
             value: false
           - value_redirect: support_hswing
+      - id: 109
+        type: bitfield
+        name: support_hswing
+        mapping:
+          - dps_val: 2
+            value: true
+          - value: false
       - id: 109
         type: bitfield
         name: support_swing
@@ -167,7 +166,7 @@ entities:
             available: support_both_swing
       - id: 110
         type: boolean
-        name: swing_real_horizontal_mode
+        name: swing_horizontal_only
         mapping:
           - dps_val: true
             value: "on"

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

@@ -902,10 +902,8 @@ class TuyaDpsConfig:
             )
             for cond in conditions:
                 avail_dp = cond.get("available")
-                if avail_dp:
-                    avail_dps = self._entity.find_dps(avail_dp)
-                    if avail_dps and not avail_dps.get_value(device):
-                        continue
+                if avail_dp and not self.mapping_available(avail_dp, device):
+                    continue
                 if c_val is not None and (_equal_or_in(c_val, cond.get("dps_val"))):
                     c_match = cond
                 # Case where matching None, need extra checks to ensure we

+ 60 - 0
tests/devices/test_goldair_portable_airconditioner.py

@@ -4,6 +4,7 @@ from homeassistant.components.climate.const import (
 )
 
 from ..const import GOLDAIR_PORTABLE_AIR_CONDITIONER_PAYLOAD
+from ..helpers import assert_device_properties_set
 from ..mixins.climate import TargetTemperatureTests
 from .base_device_tests import TuyaDeviceTestCase
 
@@ -71,9 +72,68 @@ class TestGoldairPortableAir(TargetTemperatureTests, TuyaDeviceTestCase):
         self.assertEqual(self.subject.swing_horizontal_mode, SWING_ON)
         self.dps[SWINGV_DP] = "off"
         self.assertEqual(self.subject.swing_mode, SWING_OFF)
+        self.assertEqual(self.subject.swing_horizontal_mode, SWING_ON)
         self.dps[SWINGH_DP] = False
         self.assertEqual(self.subject.swing_horizontal_mode, SWING_OFF)
 
+    def test_swing_with_vswing_unavailable(self):
+        self.dps[FEATURE_DP] = 26
+        self.dps[SWINGV_DP] = "off"
+        self.dps[SWINGH_DP] = True
+        self.assertEqual(self.subject.swing_mode, SWING_ON)
+        self.dps[SWINGV_DP] = "on"
+        self.dps[SWINGH_DP] = False
+        self.assertEqual(self.subject.swing_mode, SWING_OFF)
+
+    async def test_set_swing_modes(self):
+        self.dps[FEATURE_DP] = 27
+        async with assert_device_properties_set(
+            self.subject._device,
+            {
+                SWINGV_DP: "on",
+            },
+        ):
+            await self.subject.async_set_swing_mode(SWING_ON)
+        async with assert_device_properties_set(
+            self.subject._device,
+            {
+                SWINGV_DP: "off",
+            },
+        ):
+            await self.subject.async_set_swing_mode(SWING_OFF)
+        async with assert_device_properties_set(
+            self.subject._device,
+            {
+                SWINGH_DP: True,
+            },
+        ):
+            await self.subject.async_set_swing_horizontal_mode(SWING_ON)
+        async with assert_device_properties_set(
+            self.subject._device,
+            {
+                SWINGH_DP: False,
+            },
+        ):
+            await self.subject.async_set_swing_horizontal_mode(SWING_OFF)
+
+    async def test_set_swing_modes_only_hswing(self):
+        self.dps[FEATURE_DP] = 26
+        print(self.subject.extra_state_attributes)
+        async with assert_device_properties_set(
+            self.subject._device,
+            {
+                SWINGH_DP: True,
+            },
+        ):
+            await self.subject.async_set_swing_mode(SWING_ON)
+        async with assert_device_properties_set(
+            self.subject._device,
+            {
+                SWINGH_DP: False,
+            },
+        ):
+            await self.subject.async_set_swing_mode(SWING_OFF)
+
     def test_available(self):
         """Override the base class, as this has availability logic."""
         pass