From 09a105d9ad545e54ba62bb9681262a7a3f68bc37 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Fri, 14 Nov 2025 10:33:58 +0100 Subject: [PATCH] Migrate Tuya light (switch) to use wrapper class (#156580) --- homeassistant/components/tuya/light.py | 28 +++++--- .../components/tuya/snapshots/test_init.ambr | 2 +- .../components/tuya/snapshots/test_light.ambr | 71 +++++++++++++++++++ 3 files changed, 92 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/tuya/light.py b/homeassistant/components/tuya/light.py index 485468bda6a5..53d52c790cb1 100644 --- a/homeassistant/components/tuya/light.py +++ b/homeassistant/components/tuya/light.py @@ -29,7 +29,7 @@ from homeassistant.util.json import json_loads_object from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode, DPType, WorkMode from .entity import TuyaEntity -from .models import IntegerTypeData, find_dpcode +from .models import DPCodeBooleanWrapper, IntegerTypeData, find_dpcode from .util import get_dpcode, get_dptype, remap_value @@ -428,9 +428,15 @@ async def async_setup_entry( device = manager.device_map[device_id] if descriptions := LIGHTS.get(device.category): entities.extend( - TuyaLightEntity(device, manager, description) + TuyaLightEntity( + device, manager, description, switch_wrapper=switch_wrapper + ) for description in descriptions - if description.key in device.status + if ( + switch_wrapper := DPCodeBooleanWrapper.find_dpcode( + device, description.key, prefer_function=True + ) + ) ) async_add_entities(entities) @@ -464,11 +470,15 @@ class TuyaLightEntity(TuyaEntity, LightEntity): device: CustomerDevice, device_manager: Manager, description: TuyaLightEntityDescription, + *, + switch_wrapper: DPCodeBooleanWrapper, ) -> None: """Init TuyaHaLight.""" super().__init__(device, device_manager) self.entity_description = description self._attr_unique_id = f"{super().unique_id}{description.key}" + self._switch_wrapper = switch_wrapper + color_modes: set[ColorMode] = {ColorMode.ONOFF} # Determine DPCodes @@ -546,13 +556,15 @@ class TuyaLightEntity(TuyaEntity, LightEntity): self._fixed_color_mode = next(iter(self._attr_supported_color_modes)) @property - def is_on(self) -> bool: + def is_on(self) -> bool | None: """Return true if light is on.""" - return self.device.status.get(self.entity_description.key, False) + return self._read_wrapper(self._switch_wrapper) def turn_on(self, **kwargs: Any) -> None: """Turn on or control the light.""" - commands = [{"code": self.entity_description.key, "value": True}] + commands = [ + self._switch_wrapper.get_update_command(self.device, True), + ] if self._color_mode_dpcode and ( ATTR_WHITE in kwargs or ATTR_COLOR_TEMP_KELVIN in kwargs @@ -673,9 +685,9 @@ class TuyaLightEntity(TuyaEntity, LightEntity): self._send_command(commands) - def turn_off(self, **kwargs: Any) -> None: + async def async_turn_off(self, **kwargs: Any) -> None: """Instruct the light to turn off.""" - self._send_command([{"code": self.entity_description.key, "value": False}]) + await self._async_send_dpcode_update(self._switch_wrapper, False) @property def brightness(self) -> int | None: diff --git a/tests/components/tuya/snapshots/test_init.ambr b/tests/components/tuya/snapshots/test_init.ambr index 829110717a77..96cc09a4727c 100644 --- a/tests/components/tuya/snapshots/test_init.ambr +++ b/tests/components/tuya/snapshots/test_init.ambr @@ -6468,7 +6468,7 @@ 'labels': set({ }), 'manufacturer': 'Tuya', - 'model': 'Remote controller (unsupported)', + 'model': 'Remote controller', 'model_id': 'bngwdjsr', 'name': 'Télécommande lumières ZigBee', 'name_by_user': None, diff --git a/tests/components/tuya/snapshots/test_light.ambr b/tests/components/tuya/snapshots/test_light.ambr index f972c100766a..b2b0d1fe2f9a 100644 --- a/tests/components/tuya/snapshots/test_light.ambr +++ b/tests/components/tuya/snapshots/test_light.ambr @@ -3582,6 +3582,77 @@ 'state': 'on', }) # --- +# name: test_platform_setup_and_discovery[light.telecommande_lumieres_zigbee-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'max_color_temp_kelvin': 6500, + 'max_mireds': 500, + 'min_color_temp_kelvin': 2000, + 'min_mireds': 153, + 'supported_color_modes': list([ + , + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'light', + 'entity_category': None, + 'entity_id': 'light.telecommande_lumieres_zigbee', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': None, + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'tuya.rsjdwgnbqkyswitch_controller', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[light.telecommande_lumieres_zigbee-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'brightness': None, + 'color_mode': None, + 'color_temp': None, + 'color_temp_kelvin': None, + 'friendly_name': 'Télécommande lumières ZigBee', + 'hs_color': None, + 'max_color_temp_kelvin': 6500, + 'max_mireds': 500, + 'min_color_temp_kelvin': 2000, + 'min_mireds': 153, + 'rgb_color': None, + 'supported_color_modes': list([ + , + ]), + 'supported_features': , + 'xy_color': None, + }), + 'context': , + 'entity_id': 'light.telecommande_lumieres_zigbee', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- # name: test_platform_setup_and_discovery[light.tower_fan_ca_407g_smart_backlight-entry] EntityRegistryEntrySnapshot({ 'aliases': set({