tuya / tuya-home-assistant

Home Assistant integration for controlling Powered by Tuya (PBT) devices using Tuya Open API, maintained by the Home Assistant Community and Tuya Developer Team.
MIT License
857 stars 206 forks source link

Setting color temp and brightness with light.turn_on sends two conflicting brightness settings #316

Open hoffbaked opened 2 years ago

hoffbaked commented 2 years ago

Describe the bug When calling light.turn_on with both a brightness and color temperature, line 213 appends a second brightness code setting the brightness back to its original value with this code on line 213:

            # brightness
            ha_brightness = self.brightness
            new_range = self._tuya_brightness_range()
            tuya_brightness = self.remap(
                ha_brightness, 0, 255, new_range[0], new_range[1]
            )
            commands += [{"code": self.dp_code_bright, "value": int(tuya_brightness)}]

Expected behavior Needs to only add a brightness command if it's not in the kwargs:

        if ATTR_BRIGHTNESS not in kwargs:
            # brightness
            ha_brightness = self.brightness
            new_range = self._tuya_brightness_range()
            tuya_brightness = self.remap(
                ha_brightness, 0, 255, new_range[0], new_range[1]
            )
            commands += [{"code": self.dp_code_bright, "value": int(tuya_brightness)}]

Home Assistant Version

joe-sydney commented 2 years ago

I had a similar issue but did not diagnose it deep enough to say whether it is the same bug.

amanzie commented 2 years ago

Example DEBUG - Json POST Body showing duplicate bright_value_v2: DEBUG (SyncWorker_0) [tuya iot] Request: method = POST, url = https://openapi.tuyaeu.com/v1.0/devices/xxxx/commands, params = None, body = {'commands': [{'code': 'switch_led', 'value': True}, {'code': 'bright_value_v2', 'value': 899}, {'code': 'temp_value_v2', 'value': 922}, {'code': 'bright_value_v2', 'value': 76}]}, t = xxxx

amanzie commented 2 years ago

Further investigation. When using a lovelace color picker, all works ok because a single KWARG is provided (hs_color or brightness or color_temp).

When activating a scene, two KWARGs are provided - 'brightness' and either hs_color or color_temp., The logic gives unexpected results when two parameters are provided.

amanzie commented 2 years ago

Disclaimer: I am not a coder/python expert... but managed to hack this together which works in all the combinations I could think of.

  1. Only handled ATTR_BRIGHTNESS if ATTR_HS_COLOR not in kwargs. Replaced:
        if ATTR_BRIGHTNESS in kwargs

    With:

        if (
            ATTR_BRIGHTNESS in kwargs
            and ATTR_HS_COLOR not in kwargs
        ):
  2. For ATTR_HS_COLOR, I handled ATTR_BRIGHTNESS dependant on if it was in kwargs or not.

            # hsv v
            if ATTR_BRIGHTNESS not in kwargs:
                ha_v = self.brightness
                v_range = self._tuya_hsv_v_range()
                colour_data["v"] = int(self.remap(ha_v, 0, 255, v_range[0], v_range[1]))
    
                commands += [
                    {"code": self.dp_code_colour, "value": json.dumps(colour_data)}
                ]
    
            if ATTR_BRIGHTNESS in kwargs:
                new_range = self._tuya_brightness_range()
                colour_data["v"] = int(
                    self.remap(
                        kwargs[ATTR_BRIGHTNESS], 0, 255, new_range[0], new_range[1]
                    )
                )
                commands += [
                    {"code": self.dp_code_colour, "value": json.dumps(colour_data)}
                ]
  3. For ATTR_COLOR_TEMP, I added as per the recommendation in the original bug submission:
            if ATTR_BRIGHTNESS not in kwargs:
                # brightness
                ha_brightness = self.brightness
                new_range = self._tuya_brightness_range()
                tuya_brightness = self.remap(
                    ha_brightness, 0, 255, new_range[0], new_range[1]
                )
                commands += [{"code": self.dp_code_bright, "value": int(tuya_brightness)}]

I am sure there are far more elegant ways to do this in Python... but the logic seems to work (for scenes/dashboard cards/e.t.c)

TechyEd commented 2 years ago

Same here, I can only change brightness if used alone. If I call light.turn_on with brightness together with other parameter the brightness doesn't change: 2021-08-17 16:42:27 DEBUG (SyncWorker_1) [tuya iot] Request: method = POST, url = https://openapi.tuyaus.com/v1.0/devices/xxxxx/commands, params = None, body = {'commands': [{'code': 'switch_led', 'value': True}, {'code': 'bright_value_v2', 'value': 110}, {'code': 'temp_value_v2', 'value': 0}, {'code': 'bright_value_v2', 'value': 1000}]}, t = xxxxxxxx

tsutsuku commented 2 years ago

@amanzie Thank you for your suggestion, we will track the problem.

pabigot commented 2 years ago

I've had significant problems with scenes mixing color, white, and brightness not working, or working only after being activated multiple times. With #486 those problems have disappeared. Please review and let me know if you find any problems.

hoffbaked commented 2 years ago

Nice! I currently have it installed via HACS, so I need to do some work to try it out. It should take care of #314 , also. You might want to look at #315 , since it’s in the same area.