Sfoglia il codice sorgente

light: modify handling of effect and color_mode

Based on testing, sending an explicit color_mode to switch modes is
not supported, color_mode is read-only in HA to reflect the status of
the light, and expected to be set implicitly depending on other
settings.

Previously, code to set the effect via color mode dp was unreachable,
since color mode was always initialised to the current color_mode,
so there was always an actual color_mode to be set. So rework
color_mode auto setting code to only set it if the current mode is not
suitable for the arguments supplied.

Update tests for the fact that color_mode cannot be explicitly set,
and implicit setting only sets it when needed.

Issue #333, #309
Jason Rumney 3 anni fa
parent
commit
f2c7445366

+ 20 - 23
custom_components/tuya_local/generic/light.py

@@ -73,10 +73,9 @@ class TuyaLocalLight(TuyaLocalEntity, LightEntity):
     @property
     def color_mode(self):
         """Return the color mode of the light"""
-        if self._color_mode_dps:
-            mode = self._color_mode_dps.get_value(self._device)
-            if mode and hasattr(ColorMode, mode.upper()):
-                return ColorMode(mode)
+        from_dp = self.raw_color_mode
+        if from_dp:
+            return from_dp
 
         if self._rgbhsv_dps:
             return ColorMode.RGBW
@@ -89,6 +88,14 @@ class TuyaLocalLight(TuyaLocalEntity, LightEntity):
         else:
             return ColorMode.UNKNOWN
 
+    @property
+    def raw_color_mode(self):
+        """Return the color_mode as set from the dps."""
+        if self._color_mode_dps:
+            mode = self._color_mode_dps.get_value(self._device)
+            if mode and hasattr(ColorMode, mode.upper()):
+                return ColorMode(mode)
+
     @property
     def color_temp(self):
         """Return the color temperature in mireds"""
@@ -185,17 +192,12 @@ class TuyaLocalLight(TuyaLocalEntity, LightEntity):
 
     async def async_turn_on(self, **params):
         settings = {}
-        color_mode = params.get(ATTR_COLOR_MODE, self.color_mode)
+        color_mode = None
 
         if self._color_temp_dps and ATTR_COLOR_TEMP in params:
-            if ATTR_COLOR_MODE not in params:
+            if self.color_mode != ColorMode.COLOR_TEMP:
                 color_mode = ColorMode.COLOR_TEMP
-            if self._color_mode_dps:
-                _LOGGER.debug("Auto setting color mode to COLOR_TEMP")
-                settings = {
-                    **settings,
-                    **self._color_mode_dps.get_values_to_set(self._device, color_mode),
-                }
+
             color_temp = params.get(ATTR_COLOR_TEMP)
             r = self._color_temp_dps.range(self._device)
 
@@ -211,16 +213,11 @@ class TuyaLocalLight(TuyaLocalEntity, LightEntity):
             }
         elif self._rgbhsv_dps and (
             ATTR_RGBW_COLOR in params
-            or (ATTR_BRIGHTNESS in params and color_mode == ColorMode.RGBW)
+            or (ATTR_BRIGHTNESS in params and self.raw_color_mode == ColorMode.RGBW)
         ):
-            if ATTR_COLOR_MODE not in params:
+            if self.raw_color_mode != ColorMode.RGBW:
                 color_mode = ColorMode.RGBW
-            if self._color_mode_dps:
-                _LOGGER.debug("Auto setting color mode to RGBW")
-                settings = {
-                    **settings,
-                    **self._color_mode_dps.get_values_to_set(self._device, color_mode),
-                }
+
             rgbw = params.get(ATTR_RGBW_COLOR, self.rgbw_color or (0, 0, 0, 0))
             brightness = params.get(ATTR_BRIGHTNESS, self.brightness or 255)
             fmt = self._rgbhsv_dps.format
@@ -259,9 +256,9 @@ class TuyaLocalLight(TuyaLocalEntity, LightEntity):
                         self._rgbhsv_dps.encode_value(binary),
                     ),
                 }
-        elif self._color_mode_dps and ATTR_COLOR_MODE in params:
+        if self._color_mode_dps:
             if color_mode:
-                _LOGGER.debug(f"Explicitly setting color mode to {color_mode}")
+                _LOGGER.debug(f"Auto setting color mode to {color_mode}")
                 settings = {
                     **settings,
                     **self._color_mode_dps.get_values_to_set(self._device, color_mode),
@@ -280,7 +277,7 @@ class TuyaLocalLight(TuyaLocalEntity, LightEntity):
 
         if (
             ATTR_BRIGHTNESS in params
-            and color_mode != ColorMode.RGBW
+            and self.raw_color_mode != ColorMode.RGBW
             and self._brightness_dps
         ):
             bright = params.get(ATTR_BRIGHTNESS)

+ 4 - 6
tests/devices/test_digoo_dgsp01_dual_nightlight_switch.py

@@ -128,27 +128,25 @@ class TestDigooNightlightSwitch(BasicSwitchTests, TuyaDeviceTestCase):
             await self.light.async_turn_off()
 
     async def test_set_brightness(self):
+        self.dps[COLORMODE_DPS] = "white"
         async with assert_device_properties_set(
             self.light._device,
             {
-                COLORMODE_DPS: "white",
                 BRIGHTNESS_DPS: 128,
             },
         ):
-            await self.light.async_turn_on(color_mode=ColorMode.WHITE, brightness=128)
+            await self.light.async_turn_on(brightness=128)
 
     async def test_set_rgbw(self):
         self.dps[BRIGHTNESS_DPS] = 255
+        self.dps[COLORMODE_DPS] = "colour"
         async with assert_device_properties_set(
             self.light._device,
             {
-                COLORMODE_DPS: "colour",
                 RGBW_DPS: "ff000000006464",
             },
         ):
-            await self.light.async_turn_on(
-                color_mode=ColorMode.RGBW, rgbw_color=(255, 0, 0, 255)
-            )
+            await self.light.async_turn_on(rgbw_color=(255, 0, 0, 255))
 
     def test_extra_state_attributes_set(self):
         self.dps[UNKNOWN32_DPS] = "32"

+ 4 - 6
tests/devices/test_moes_rgb_socket.py

@@ -177,29 +177,27 @@ class TestMoesRGBWSocket(
 
     async def test_set_brightness(self):
         self.dps[LIGHT_DPS] = True
+        self.dps[MODE_DPS] = "white"
         async with assert_device_properties_set(
             self.light._device,
             {
-                MODE_DPS: "white",
                 BRIGHTNESS_DPS: 128,
             },
         ):
-            await self.light.async_turn_on(color_mode=ColorMode.WHITE, brightness=128)
+            await self.light.async_turn_on(brightness=128)
 
     async def test_set_rgbw(self):
         self.dps[BRIGHTNESS_DPS] = 255
         self.dps[LIGHT_DPS] = True
+        self.dps[MODE_DPS] = "colour"
 
         async with assert_device_properties_set(
             self.light._device,
             {
-                MODE_DPS: "colour",
                 RGBW_DPS: "ff00000000ffff",
             },
         ):
-            await self.light.async_turn_on(
-                color_mode=ColorMode.RGBW, rgbw_color=(255, 0, 0, 255)
-            )
+            await self.light.async_turn_on(rgbw_color=(255, 0, 0, 255))
 
     def test_extra_state_attributes_set(self):
         self.dps[UNKNOWN4_DPS] = 4

+ 31 - 4
tests/devices/test_rgbcw_lightbulb.py

@@ -114,20 +114,48 @@ class TestRGBCWLightbulb(BasicNumberTests, TuyaDeviceTestCase):
         ):
             await self.subject.async_turn_off()
 
-    async def test_set_brightness(self):
+    async def test_set_brightness_white(self):
         self.dps[SWITCH_DPS] = True
+        self.dps[MODE_DPS] = "white"
+
         async with assert_device_properties_set(
             self.subject._device,
             {
-                MODE_DPS: "white",
                 BRIGHTNESS_DPS: 502,
             },
         ):
-            await self.subject.async_turn_on(color_mode=ColorMode.WHITE, brightness=128)
+            await self.subject.async_turn_on(brightness=128)
+
+    async def test_set_brightness_color(self):
+        self.dps[SWITCH_DPS] = True
+        self.dps[MODE_DPS] = "colour"
+        self.dps[HSV_DPS] = "000003e803e8"
+        async with assert_device_properties_set(
+            self.subject._device,
+            {
+                HSV_DPS: "000003e801f6",
+            },
+        ):
+            await self.subject.async_turn_on(brightness=128)
 
     async def test_set_rgbw(self):
         self.dps[BRIGHTNESS_DPS] = 1000
         self.dps[SWITCH_DPS] = True
+        self.dps[MODE_DPS] = "colour"
+        async with assert_device_properties_set(
+            self.subject._device,
+            {
+                HSV_DPS: "000003e803e8",
+            },
+        ):
+            await self.subject.async_turn_on(
+                rgbw_color=(255, 0, 0, 255),
+            )
+
+    async def test_set_rgbw_from_white(self):
+        self.dps[BRIGHTNESS_DPS] = 1000
+        self.dps[SWITCH_DPS] = True
+        self.dps[MODE_DPS] = "white"
         async with assert_device_properties_set(
             self.subject._device,
             {
@@ -136,7 +164,6 @@ class TestRGBCWLightbulb(BasicNumberTests, TuyaDeviceTestCase):
             },
         ):
             await self.subject.async_turn_on(
-                color_mode=ColorMode.RGBW,
                 rgbw_color=(255, 0, 0, 255),
             )