diff --git a/homeassistant/components/tuya/quirks/__init__.py b/homeassistant/components/tuya/quirks/__init__.py index fd8fa0dbfe8..d8747c538fe 100644 --- a/homeassistant/components/tuya/quirks/__init__.py +++ b/homeassistant/components/tuya/quirks/__init__.py @@ -8,7 +8,12 @@ import pathlib import pkgutil import sys -from .device_quirk import TuyaCoverDefinition, TuyaDeviceQuirk, TuyaSensorDefinition +from .device_quirk import ( + TuyaCoverDefinition, + TuyaDeviceQuirk, + TuyaSelectDefinition, + TuyaSensorDefinition, +) from .homeassistant import TuyaCoverDeviceClass, TuyaSensorDeviceClass, parse_enum from .registry import QuirksRegistry @@ -18,6 +23,7 @@ __all__ = [ "TuyaCoverDefinition", "TuyaCoverDeviceClass", "TuyaDeviceQuirk", + "TuyaSelectDefinition", "TuyaSensorDefinition", "TuyaSensorDeviceClass", "parse_enum", diff --git a/homeassistant/components/tuya/quirks/device_quirk.py b/homeassistant/components/tuya/quirks/device_quirk.py index b876ea469d5..083bb46648a 100644 --- a/homeassistant/components/tuya/quirks/device_quirk.py +++ b/homeassistant/components/tuya/quirks/device_quirk.py @@ -39,6 +39,13 @@ class TuyaCoverDefinition(BaseTuyaDefinition): set_position_dp_code: str | None = None +@dataclass(kw_only=True) +class TuyaSelectDefinition(BaseTuyaDefinition): + """Definition for a select entity.""" + + state_translations: dict[str, str] | None = None + + @dataclass(kw_only=True) class TuyaSensorDefinition(BaseTuyaDefinition): """Definition for a sensor entity.""" @@ -51,12 +58,14 @@ class TuyaDeviceQuirk: _applies_to: list[tuple[str, str]] cover_definitions: list[TuyaCoverDefinition] + select_definitions: list[TuyaSelectDefinition] sensor_definitions: list[TuyaSensorDefinition] def __init__(self) -> None: """Initialize the quirk.""" self._applies_to = [] self.cover_definitions = [] + self.select_definitions = [] self.sensor_definitions = [] current_frame = inspect.currentframe() @@ -104,6 +113,28 @@ class TuyaDeviceQuirk: ) return self + def add_select( + self, + *, + key: str, + translation_key: str, + translation_string: str, + entity_category: TuyaEntityCategory | None = None, + # Select specific + state_translations: dict[str, str] | None = None, + ) -> Self: + """Add select definition.""" + self.select_definitions.append( + TuyaSelectDefinition( + key=key, + translation_key=translation_key, + translation_string=translation_string, + entity_category=entity_category, + state_translations=state_translations, + ) + ) + return self + def add_sensor( self, *, diff --git a/homeassistant/components/tuya/quirks/device_quirks/cl.py b/homeassistant/components/tuya/quirks/device_quirks/cl.py index 5251640e296..238ec77a5a4 100644 --- a/homeassistant/components/tuya/quirks/device_quirks/cl.py +++ b/homeassistant/components/tuya/quirks/device_quirks/cl.py @@ -20,6 +20,13 @@ from ..homeassistant import TuyaCoverDeviceClass, TuyaEntityCategory set_position_dp_code="percent_control", device_class=TuyaCoverDeviceClass.CURTAIN, ) + .add_select( + key="control_back_mode", + translation_key="curtain_motor_mode", + translation_string="Motor mode", + entity_category=TuyaEntityCategory.CONFIG, + state_translations={"forward": "Forward", "back": "Back"}, + ) .register(TUYA_QUIRKS_REGISTRY) ) ( @@ -34,6 +41,13 @@ from ..homeassistant import TuyaCoverDeviceClass, TuyaEntityCategory current_state_dp_code="control", device_class=TuyaCoverDeviceClass.CURTAIN, ) + .add_select( + key="control_back_mode", + translation_key="curtain_motor_mode", + translation_string="Motor mode", + entity_category=TuyaEntityCategory.CONFIG, + state_translations={"forward": "Forward", "back": "Back"}, + ) .add_sensor( key="time_total", translation_key="last_operation_duration", diff --git a/homeassistant/components/tuya/select.py b/homeassistant/components/tuya/select.py index 6a4d8d7b488..dff4812cbed 100644 --- a/homeassistant/components/tuya/select.py +++ b/homeassistant/components/tuya/select.py @@ -13,6 +13,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode, DPType from .entity import TuyaEntity +from .quirks import TUYA_QUIRKS_REGISTRY, TuyaSelectDefinition, parse_enum # All descriptions can be found here. Mostly the Enum data types in the # default instructions set of each category end up being a select. @@ -343,6 +344,16 @@ SELECTS[DeviceCategory.DGHSXJ] = SELECTS[DeviceCategory.SP] SELECTS[DeviceCategory.PC] = SELECTS[DeviceCategory.KG] +def _create_quirk_description( + definition: TuyaSelectDefinition, +) -> SelectEntityDescription: + return SelectEntityDescription( + key=DPCode(definition.key), + translation_key=definition.translation_key, + entity_category=parse_enum(EntityCategory, definition.entity_category), + ) + + async def async_setup_entry( hass: HomeAssistant, entry: TuyaConfigEntry, @@ -357,7 +368,15 @@ async def async_setup_entry( entities: list[TuyaSelectEntity] = [] for device_id in device_ids: device = manager.device_map[device_id] - if descriptions := SELECTS.get(device.category): + if quirk := TUYA_QUIRKS_REGISTRY.get_quirk_for_device(device): + entities.extend( + TuyaSelectEntity( + device, manager, _create_quirk_description(definition) + ) + for definition in quirk.select_definitions + if definition.key in device.status + ) + elif descriptions := SELECTS.get(device.category): entities.extend( TuyaSelectEntity(device, manager, description) for description in descriptions diff --git a/homeassistant/components/tuya/sensor.py b/homeassistant/components/tuya/sensor.py index 89c61cd3892..55e9ff4f2a7 100644 --- a/homeassistant/components/tuya/sensor.py +++ b/homeassistant/components/tuya/sensor.py @@ -1667,10 +1667,7 @@ async def async_setup_entry( device, manager, _create_quirk_description(definition) ) for definition in quirk.sensor_definitions - if ( - definition.key in device.function - or definition.key in device.status_range - ) + if definition.key in device.status ) elif descriptions := SENSORS.get(device.category): entities.extend(