diff --git a/homeassistant/components/tuya/alarm_control_panel.py b/homeassistant/components/tuya/alarm_control_panel.py index a89c97e2be2e..0d1b96f654df 100644 --- a/homeassistant/components/tuya/alarm_control_panel.py +++ b/homeassistant/components/tuya/alarm_control_panel.py @@ -1,5 +1,6 @@ """Support for Tuya Alarm.""" +from dataclasses import dataclass from typing import override from tuya_device_handlers.definition.alarm_control_panel import ( @@ -24,14 +25,22 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription -ALARM: dict[DeviceCategory, AlarmControlPanelEntityDescription] = { - DeviceCategory.MAL: AlarmControlPanelEntityDescription( + +@dataclass(frozen=True) +class TuyaAlarmControlPanelEntityDescription( + TuyaEntityDescription, AlarmControlPanelEntityDescription +): + """Describes a Tuya alarm control panel entity.""" + + +ALARM: dict[DeviceCategory, TuyaAlarmControlPanelEntityDescription] = { + DeviceCategory.MAL: TuyaAlarmControlPanelEntityDescription( key=DPCode.MASTER_MODE, name="Alarm", ), - DeviceCategory.WG2: AlarmControlPanelEntityDescription( + DeviceCategory.WG2: TuyaAlarmControlPanelEntityDescription( key=DPCode.MASTER_MODE, name="Alarm", ), @@ -92,7 +101,7 @@ class TuyaAlarmEntity(TuyaEntity, AlarmControlPanelEntity): self, device: CustomerDevice, device_manager: Manager, - description: AlarmControlPanelEntityDescription, + description: TuyaAlarmControlPanelEntityDescription, definition: AlarmControlPanelDefinition, ) -> None: """Init Tuya Alarm.""" diff --git a/homeassistant/components/tuya/binary_sensor.py b/homeassistant/components/tuya/binary_sensor.py index af5feb3eda25..895ecaaac441 100644 --- a/homeassistant/components/tuya/binary_sensor.py +++ b/homeassistant/components/tuya/binary_sensor.py @@ -21,11 +21,13 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription @dataclass(frozen=True) -class TuyaBinarySensorEntityDescription(BinarySensorEntityDescription): +class TuyaBinarySensorEntityDescription( + TuyaEntityDescription, BinarySensorEntityDescription +): """Describes a Tuya binary sensor.""" # DPCode, to use. If None, the key will be used as DPCode diff --git a/homeassistant/components/tuya/button.py b/homeassistant/components/tuya/button.py index 3d9c5148f20d..a873e71b6d6f 100644 --- a/homeassistant/components/tuya/button.py +++ b/homeassistant/components/tuya/button.py @@ -1,5 +1,6 @@ """Support for Tuya buttons.""" +from dataclasses import dataclass from typing import override from tuya_device_handlers.definition.button import ( @@ -20,57 +21,63 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription -BUTTONS: dict[DeviceCategory, tuple[ButtonEntityDescription, ...]] = { + +@dataclass(frozen=True) +class TuyaButtonEntityDescription(TuyaEntityDescription, ButtonEntityDescription): + """Describes a Tuya button entity.""" + + +BUTTONS: dict[DeviceCategory, tuple[TuyaButtonEntityDescription, ...]] = { DeviceCategory.HXD: ( - ButtonEntityDescription( + TuyaButtonEntityDescription( key=DPCode.SWITCH_USB6, translation_key="snooze", ), ), DeviceCategory.MSP: ( - ButtonEntityDescription( + TuyaButtonEntityDescription( key=DPCode.FACTORY_RESET, translation_key="factory_reset", entity_category=EntityCategory.DIAGNOSTIC, entity_registry_enabled_default=False, ), - ButtonEntityDescription( + TuyaButtonEntityDescription( key=DPCode.MANUAL_CLEAN, translation_key="manual_clean", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.SD: ( - ButtonEntityDescription( + TuyaButtonEntityDescription( key=DPCode.RESET_DUSTER_CLOTH, translation_key="reset_duster_cloth", entity_category=EntityCategory.CONFIG, ), - ButtonEntityDescription( + TuyaButtonEntityDescription( key=DPCode.RESET_EDGE_BRUSH, translation_key="reset_edge_brush", entity_category=EntityCategory.CONFIG, ), - ButtonEntityDescription( + TuyaButtonEntityDescription( key=DPCode.RESET_FILTER, translation_key="reset_filter", entity_category=EntityCategory.CONFIG, ), - ButtonEntityDescription( + TuyaButtonEntityDescription( key=DPCode.RESET_MAP, translation_key="reset_map", entity_category=EntityCategory.CONFIG, ), - ButtonEntityDescription( + TuyaButtonEntityDescription( key=DPCode.RESET_ROLL_BRUSH, translation_key="reset_roll_brush", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.SP: ( - ButtonEntityDescription( + TuyaButtonEntityDescription( key=DPCode.DEVICE_RESTART, device_class=ButtonDeviceClass.RESTART, entity_category=EntityCategory.CONFIG, @@ -116,7 +123,7 @@ class TuyaButtonEntity(TuyaEntity, ButtonEntity): self, device: CustomerDevice, device_manager: Manager, - description: ButtonEntityDescription, + description: TuyaButtonEntityDescription, definition: ButtonDefinition, ) -> None: """Init Tuya button.""" diff --git a/homeassistant/components/tuya/camera.py b/homeassistant/components/tuya/camera.py index 277fa2b17cd4..7fa7c74ceef8 100644 --- a/homeassistant/components/tuya/camera.py +++ b/homeassistant/components/tuya/camera.py @@ -1,5 +1,6 @@ """Support for Tuya cameras.""" +from dataclasses import dataclass from typing import override from tuya_device_handlers.definition.camera import ( @@ -20,11 +21,17 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription -CAMERAS: dict[DeviceCategory, CameraEntityDescription] = { - DeviceCategory.DGHSXJ: CameraEntityDescription(key=""), - DeviceCategory.SP: CameraEntityDescription(key=""), + +@dataclass(frozen=True) +class TuyaCameraEntityDescription(TuyaEntityDescription, CameraEntityDescription): + """Describes a Tuya camera entity.""" + + +CAMERAS: dict[DeviceCategory, TuyaCameraEntityDescription] = { + DeviceCategory.DGHSXJ: TuyaCameraEntityDescription(key=""), + DeviceCategory.SP: TuyaCameraEntityDescription(key=""), } @@ -69,7 +76,7 @@ class TuyaCameraEntity(TuyaEntity, CameraEntity): self, device: CustomerDevice, device_manager: Manager, - description: CameraEntityDescription, + description: TuyaCameraEntityDescription, definition: CameraDefinition, ) -> None: """Init Tuya Camera.""" diff --git a/homeassistant/components/tuya/climate.py b/homeassistant/components/tuya/climate.py index 4de024e52787..1b7039341d82 100644 --- a/homeassistant/components/tuya/climate.py +++ b/homeassistant/components/tuya/climate.py @@ -33,7 +33,7 @@ from homeassistant.util.unit_conversion import TemperatureConverter from .const import TUYA_DISCOVERY_NEW, DeviceCategory from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription from .util import get_temperature_unit _TUYA_TO_HA_HVACMODE_MAPPINGS = { @@ -63,7 +63,7 @@ _HA_TO_TUYA_TEMPERATURE = { @dataclass(frozen=True, kw_only=True) -class TuyaClimateEntityDescription(ClimateEntityDescription): +class TuyaClimateEntityDescription(TuyaEntityDescription, ClimateEntityDescription): """Describe an Tuya climate entity.""" switch_only_hvac_mode: HVACMode diff --git a/homeassistant/components/tuya/cover.py b/homeassistant/components/tuya/cover.py index b834b438c94e..d1b0b9753fbf 100644 --- a/homeassistant/components/tuya/cover.py +++ b/homeassistant/components/tuya/cover.py @@ -35,11 +35,11 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription @dataclass(frozen=True) -class TuyaCoverEntityDescription(CoverEntityDescription): +class TuyaCoverEntityDescription(TuyaEntityDescription, CoverEntityDescription): """Describe a Tuya cover entity.""" current_state: DPCode | tuple[DPCode, ...] | None = None diff --git a/homeassistant/components/tuya/entity.py b/homeassistant/components/tuya/entity.py index fb5326038388..a98cdbf9813f 100644 --- a/homeassistant/components/tuya/entity.py +++ b/homeassistant/components/tuya/entity.py @@ -1,5 +1,6 @@ """Tuya Home Assistant Base Device Model.""" +from dataclasses import dataclass from typing import Any, override from tuya_device_handlers.device_wrapper import DeviceWrapper @@ -12,6 +13,11 @@ from homeassistant.helpers.entity import Entity, EntityDescription from .const import DOMAIN, LOGGER, TUYA_HA_SIGNAL_UPDATE_ENTITY +@dataclass(frozen=True) +class TuyaEntityDescription(EntityDescription): + """Describes a Tuya entity.""" + + class TuyaEntity(Entity): """Tuya base device.""" @@ -22,7 +28,7 @@ class TuyaEntity(Entity): self, device: CustomerDevice, device_manager: Manager, - description: EntityDescription, + description: TuyaEntityDescription, ) -> None: """Init TuyaEntity.""" self._attr_device_info = DeviceInfo(identifiers={(DOMAIN, device.id)}) diff --git a/homeassistant/components/tuya/event.py b/homeassistant/components/tuya/event.py index b863f9db1761..94f3af59923c 100644 --- a/homeassistant/components/tuya/event.py +++ b/homeassistant/components/tuya/event.py @@ -26,11 +26,11 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription @dataclass(frozen=True) -class TuyaEventEntityDescription(EventEntityDescription): +class TuyaEventEntityDescription(TuyaEntityDescription, EventEntityDescription): """Describe a Tuya Event entity.""" wrapper_class: type[DPCodeTypeInformationWrapper] = SimpleEventEnumWrapper @@ -150,13 +150,13 @@ async def async_setup_entry( class TuyaEventEntity(TuyaEntity, EventEntity): """Tuya Event Entity.""" - entity_description: EventEntityDescription + entity_description: TuyaEventEntityDescription def __init__( self, device: CustomerDevice, device_manager: Manager, - description: EventEntityDescription, + description: TuyaEventEntityDescription, definition: EventDefinition, ) -> None: """Init Tuya event entity.""" diff --git a/homeassistant/components/tuya/fan.py b/homeassistant/components/tuya/fan.py index d17015937332..20d5265cbe7a 100644 --- a/homeassistant/components/tuya/fan.py +++ b/homeassistant/components/tuya/fan.py @@ -1,5 +1,6 @@ """Support for Tuya Fan.""" +from dataclasses import dataclass from typing import Any, override from tuya_device_handlers.definition.fan import FanDefinition, get_default_definition @@ -19,15 +20,21 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription -FANS: dict[DeviceCategory, FanEntityDescription] = { - DeviceCategory.CS: FanEntityDescription(key=""), - DeviceCategory.FS: FanEntityDescription(key=""), - DeviceCategory.FSD: FanEntityDescription(key=""), - DeviceCategory.FSKG: FanEntityDescription(key=""), - DeviceCategory.KJ: FanEntityDescription(key=""), - DeviceCategory.KS: FanEntityDescription(key=""), + +@dataclass(frozen=True) +class TuyaFanEntityDescription(TuyaEntityDescription, FanEntityDescription): + """Describes a Tuya fan entity.""" + + +FANS: dict[DeviceCategory, TuyaFanEntityDescription] = { + DeviceCategory.CS: TuyaFanEntityDescription(key=""), + DeviceCategory.FS: TuyaFanEntityDescription(key=""), + DeviceCategory.FSD: TuyaFanEntityDescription(key=""), + DeviceCategory.FSKG: TuyaFanEntityDescription(key=""), + DeviceCategory.KJ: TuyaFanEntityDescription(key=""), + DeviceCategory.KS: TuyaFanEntityDescription(key=""), } _TUYA_TO_HA_DIRECTION_MAPPINGS = { @@ -75,7 +82,7 @@ class TuyaFanEntity(TuyaEntity, FanEntity): self, device: CustomerDevice, device_manager: Manager, - description: FanEntityDescription, + description: TuyaFanEntityDescription, definition: FanDefinition, ) -> None: """Init Tuya Fan Device.""" diff --git a/homeassistant/components/tuya/humidifier.py b/homeassistant/components/tuya/humidifier.py index c76fd3414234..42aff1b4d780 100644 --- a/homeassistant/components/tuya/humidifier.py +++ b/homeassistant/components/tuya/humidifier.py @@ -21,12 +21,14 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription from .util import ActionDPCodeNotFoundError @dataclass(frozen=True) -class TuyaHumidifierEntityDescription(HumidifierEntityDescription): +class TuyaHumidifierEntityDescription( + TuyaEntityDescription, HumidifierEntityDescription +): """Describe an Tuya (de)humidifier entity.""" # DPCode, to use. If None, the key will be used as DPCode diff --git a/homeassistant/components/tuya/light.py b/homeassistant/components/tuya/light.py index 49525b980fc2..35a3cb5fafec 100644 --- a/homeassistant/components/tuya/light.py +++ b/homeassistant/components/tuya/light.py @@ -29,11 +29,11 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode, WorkMode from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription @dataclass(frozen=True) -class TuyaLightEntityDescription(LightEntityDescription): +class TuyaLightEntityDescription(TuyaEntityDescription, LightEntityDescription): """Describe an Tuya light entity.""" brightness_max: DPCode | None = None diff --git a/homeassistant/components/tuya/number.py b/homeassistant/components/tuya/number.py index e16e4a622dc8..5b9b59ddf500 100644 --- a/homeassistant/components/tuya/number.py +++ b/homeassistant/components/tuya/number.py @@ -1,5 +1,6 @@ """Support for Tuya number.""" +from dataclasses import dataclass from typing import override from tuya_device_handlers.definition.number import ( @@ -27,50 +28,56 @@ from .const import ( DPCode, ) from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription from .util import get_device_temp_unit_convert -NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { + +@dataclass(frozen=True) +class TuyaNumberEntityDescription(TuyaEntityDescription, NumberEntityDescription): + """Describes a Tuya number entity.""" + + +NUMBERS: dict[DeviceCategory, tuple[TuyaNumberEntityDescription, ...]] = { DeviceCategory.BH: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.TEMP_SET, translation_key="temperature", device_class=NumberDeviceClass.TEMPERATURE, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.TEMP_SET_F, translation_key="temperature", device_class=NumberDeviceClass.TEMPERATURE, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.TEMP_BOILING_C, translation_key="temperature_after_boiling", device_class=NumberDeviceClass.TEMPERATURE, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.TEMP_BOILING_F, translation_key="temperature_after_boiling", device_class=NumberDeviceClass.TEMPERATURE, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.WARM_TIME, translation_key="heat_preservation_time", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.BZYD: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.VOLUME_SET, translation_key="volume", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.CO2BJ: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.ALARM_TIME, translation_key="alarm_duration", native_unit_of_measurement=UnitOfTime.SECONDS, @@ -79,25 +86,25 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), ), DeviceCategory.CWWSQ: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.MANUAL_FEED, translation_key="feed", ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.VOICE_TIMES, translation_key="voice_times", ), ), DeviceCategory.CZ: ( # Two-channel current transformer meters warn above these thresholds - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.WARN_POWER1, translation_key="indexed_power_warning_threshold", translation_placeholders={"index": "1"}, device_class=NumberDeviceClass.POWER, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.WARN_POWER2, translation_key="indexed_power_warning_threshold", translation_placeholders={"index": "2"}, @@ -106,93 +113,93 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), ), DeviceCategory.DGNBJ: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.ALARM_TIME, translation_key="time", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.FS: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.TEMP, translation_key="temperature", device_class=NumberDeviceClass.TEMPERATURE, ), ), DeviceCategory.HPS: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.SENSITIVITY, translation_key="sensitivity", entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.NEAR_DETECTION, translation_key="near_detection", device_class=NumberDeviceClass.DISTANCE, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.FAR_DETECTION, translation_key="far_detection", device_class=NumberDeviceClass.DISTANCE, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.TARGET_DIS_CLOSEST, translation_key="target_dis_closest", device_class=NumberDeviceClass.DISTANCE, ), ), DeviceCategory.JSQ: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.TEMP_SET, translation_key="temperature", device_class=NumberDeviceClass.TEMPERATURE, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.TEMP_SET_F, translation_key="temperature", device_class=NumberDeviceClass.TEMPERATURE, ), ), DeviceCategory.KFJ: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.WATER_SET, translation_key="water_level", entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.TEMP_SET, translation_key="temperature", device_class=NumberDeviceClass.TEMPERATURE, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.WARM_TIME, translation_key="heat_preservation_time", entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.POWDER_SET, translation_key="powder", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.MAL: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.DELAY_SET, # This setting is called "Arm Delay" in the official Tuya app translation_key="arm_delay", device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.ALARM_DELAY_TIME, translation_key="alarm_delay", device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.ALARM_TIME, # This setting is called "Siren Duration" in the official Tuya app translation_key="siren_duration", @@ -201,7 +208,7 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), ), DeviceCategory.MSP: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.DELAY_CLEAN_TIME, translation_key="delay_clean_time", device_class=NumberDeviceClass.DURATION, @@ -209,37 +216,37 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), ), DeviceCategory.MZJ: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COOK_TEMPERATURE, translation_key="cook_temperature", entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COOK_TIME, translation_key="cook_time", native_unit_of_measurement=UnitOfTime.MINUTES, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.CLOUD_RECIPE_NUMBER, translation_key="cloud_recipe", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.QCCDZ: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.CHARGE_CUR_SET, translation_key="charging_current", device_class=NumberDeviceClass.CURRENT, ), ), DeviceCategory.SWTZ: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COOK_TEMPERATURE, translation_key="cook_temperature", entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COOK_TEMPERATURE_2, translation_key="indexed_cook_temperature", translation_placeholders={"index": "2"}, @@ -247,7 +254,7 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), ), DeviceCategory.SD: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.VOLUME_SET, translation_key="volume", entity_category=EntityCategory.CONFIG, @@ -255,63 +262,63 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), DeviceCategory.SFKZQ: ( # Controls the irrigation duration for indexed water valves - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COUNTDOWN, translation_key="irrigation_duration", device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), # Controls the irrigation duration for indexed water valves - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COUNTDOWN_1, translation_key="indexed_irrigation_duration", translation_placeholders={"index": "1"}, device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COUNTDOWN_2, translation_key="indexed_irrigation_duration", translation_placeholders={"index": "2"}, device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COUNTDOWN_3, translation_key="indexed_irrigation_duration", translation_placeholders={"index": "3"}, device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COUNTDOWN_4, translation_key="indexed_irrigation_duration", translation_placeholders={"index": "4"}, device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COUNTDOWN_5, translation_key="indexed_irrigation_duration", translation_placeholders={"index": "5"}, device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COUNTDOWN_6, translation_key="indexed_irrigation_duration", translation_placeholders={"index": "6"}, device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COUNTDOWN_7, translation_key="indexed_irrigation_duration", translation_placeholders={"index": "7"}, device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.COUNTDOWN_8, translation_key="indexed_irrigation_duration", translation_placeholders={"index": "8"}, @@ -320,85 +327,85 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), ), DeviceCategory.SGBJ: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.ALARM_TIME, translation_key="time", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.SP: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BASIC_DEVICE_VOLUME, translation_key="volume", entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.IPC_BRIGHT, translation_key="video_brightness", entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.IPC_CONTRAST, translation_key="video_contrast", entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.IPC_SHARP, translation_key="video_sharpness", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.SZJQR: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.ARM_DOWN_PERCENT, translation_key="move_down", native_unit_of_measurement=UnitOfRatio.PERCENTAGE, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.ARM_UP_PERCENT, translation_key="move_up", native_unit_of_measurement=UnitOfRatio.PERCENTAGE, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.CLICK_SUSTAIN_TIME, translation_key="down_delay", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.TGKG: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BRIGHTNESS_MIN_1, translation_key="indexed_minimum_brightness", translation_placeholders={"index": "1"}, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BRIGHTNESS_MAX_1, translation_key="indexed_maximum_brightness", translation_placeholders={"index": "1"}, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BRIGHTNESS_MIN_2, translation_key="indexed_minimum_brightness", translation_placeholders={"index": "2"}, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BRIGHTNESS_MAX_2, translation_key="indexed_maximum_brightness", translation_placeholders={"index": "2"}, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BRIGHTNESS_MIN_3, translation_key="indexed_minimum_brightness", translation_placeholders={"index": "3"}, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BRIGHTNESS_MAX_3, translation_key="indexed_maximum_brightness", translation_placeholders={"index": "3"}, @@ -406,25 +413,25 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), ), DeviceCategory.TGQ: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BRIGHTNESS_MIN_1, translation_key="indexed_minimum_brightness", translation_placeholders={"index": "1"}, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BRIGHTNESS_MAX_1, translation_key="indexed_maximum_brightness", translation_placeholders={"index": "1"}, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BRIGHTNESS_MIN_2, translation_key="indexed_minimum_brightness", translation_placeholders={"index": "2"}, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BRIGHTNESS_MAX_2, translation_key="indexed_maximum_brightness", translation_placeholders={"index": "2"}, @@ -432,20 +439,20 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), ), DeviceCategory.WG2: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.DELAY_SET, # This setting is called "Arm Delay" in the official Tuya app translation_key="arm_delay", device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.ALARM_DELAY_TIME, translation_key="alarm_delay", device_class=NumberDeviceClass.DURATION, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.ALARM_TIME, # This setting is called "Siren Duration" in the official Tuya app translation_key="siren_duration", @@ -454,19 +461,19 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), ), DeviceCategory.WK: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.TEMP_CORRECTION, translation_key="temp_correction", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.XNYJCN: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.BACKUP_RESERVE, translation_key="battery_backup_reserve", entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.OUTPUT_POWER_LIMIT, translation_key="inverter_output_power_limit", device_class=NumberDeviceClass.POWER, @@ -474,23 +481,23 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), ), DeviceCategory.YWCGQ: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.MAX_SET, translation_key="alarm_maximum", entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.MINI_SET, translation_key="alarm_minimum", entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.INSTALLATION_HEIGHT, translation_key="installation_height", device_class=NumberDeviceClass.DISTANCE, entity_category=EntityCategory.CONFIG, ), - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.LIQUID_DEPTH_MAX, translation_key="maximum_liquid_depth", device_class=NumberDeviceClass.DISTANCE, @@ -498,14 +505,14 @@ NUMBERS: dict[DeviceCategory, tuple[NumberEntityDescription, ...]] = { ), ), DeviceCategory.ZD: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.SENSITIVITY, translation_key="sensitivity", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.ZNRB: ( - NumberEntityDescription( + TuyaNumberEntityDescription( key=DPCode.TEMP_SET, translation_key="temperature", device_class=NumberDeviceClass.TEMPERATURE, @@ -554,7 +561,7 @@ class TuyaNumberEntity(TuyaEntity, NumberEntity): self, device: CustomerDevice, device_manager: Manager, - description: NumberEntityDescription, + description: TuyaNumberEntityDescription, definition: NumberDefinition, ) -> None: """Initialize a Tuya number entity.""" diff --git a/homeassistant/components/tuya/select.py b/homeassistant/components/tuya/select.py index 43cb4a509eeb..e6acaf1f4418 100644 --- a/homeassistant/components/tuya/select.py +++ b/homeassistant/components/tuya/select.py @@ -1,5 +1,6 @@ """Support for Tuya select.""" +from dataclasses import dataclass from typing import override from tuya_device_handlers.definition.select import ( @@ -16,81 +17,87 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription + # All descriptions can be found here. Mostly the Enum data types in the # default instructions set of each category end up being a select. -SELECTS: dict[DeviceCategory, tuple[SelectEntityDescription, ...]] = { +@dataclass(frozen=True) +class TuyaSelectEntityDescription(TuyaEntityDescription, SelectEntityDescription): + """Describes a Tuya select entity.""" + + +SELECTS: dict[DeviceCategory, tuple[TuyaSelectEntityDescription, ...]] = { DeviceCategory.BH: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.TEMP_SETTING_QUICK_C, entity_category=EntityCategory.CONFIG, translation_key="quick_heat_temperature", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.WORK_TYPE, entity_category=EntityCategory.CONFIG, translation_key="kettle_work_mode", ), ), DeviceCategory.CL: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.CONTROL_BACK_MODE, entity_category=EntityCategory.CONFIG, translation_key="curtain_motor_mode", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.MODE, entity_category=EntityCategory.CONFIG, translation_key="curtain_mode", ), ), DeviceCategory.CO2BJ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.ALARM_VOLUME, translation_key="volume", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.CS: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.COUNTDOWN_SET, entity_category=EntityCategory.CONFIG, translation_key="countdown", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.DEHUMIDITY_SET_ENUM, translation_key="target_humidity", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.CWJWQ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.WORK_MODE, entity_category=EntityCategory.CONFIG, translation_key="odor_elimination_mode", ), ), DeviceCategory.DGNBJ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.ALARM_VOLUME, translation_key="volume", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.DR: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LEVEL, icon="mdi:thermometer-lines", translation_key="blanket_level", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LEVEL_1, icon="mdi:thermometer-lines", translation_key="indexed_blanket_level", translation_placeholders={"index": "1"}, ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LEVEL_2, icon="mdi:thermometer-lines", translation_key="indexed_blanket_level", @@ -98,122 +105,122 @@ SELECTS: dict[DeviceCategory, tuple[SelectEntityDescription, ...]] = { ), ), DeviceCategory.FS: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.FAN_VERTICAL, entity_category=EntityCategory.CONFIG, translation_key="vertical_fan_angle", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.FAN_HORIZONTAL, entity_category=EntityCategory.CONFIG, translation_key="horizontal_fan_angle", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.COUNTDOWN, entity_category=EntityCategory.CONFIG, translation_key="countdown", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.COUNTDOWN_SET, entity_category=EntityCategory.CONFIG, translation_key="countdown", ), ), DeviceCategory.JSQ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.SPRAY_MODE, entity_category=EntityCategory.CONFIG, translation_key="humidifier_spray_mode", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LEVEL, entity_category=EntityCategory.CONFIG, translation_key="humidifier_level", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.MOODLIGHTING, entity_category=EntityCategory.CONFIG, translation_key="humidifier_moodlighting", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.COUNTDOWN, entity_category=EntityCategory.CONFIG, translation_key="countdown", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.COUNTDOWN_SET, entity_category=EntityCategory.CONFIG, translation_key="countdown", ), ), DeviceCategory.KFJ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.CUP_NUMBER, translation_key="cups", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.CONCENTRATION_SET, translation_key="concentration", entity_category=EntityCategory.CONFIG, ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.MATERIAL, translation_key="material", entity_category=EntityCategory.CONFIG, ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.MODE, translation_key="mode", ), ), DeviceCategory.KG: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.RELAY_STATUS, entity_category=EntityCategory.CONFIG, translation_key="relay_status", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LIGHT_MODE, entity_category=EntityCategory.CONFIG, translation_key="light_mode", ), ), DeviceCategory.KJ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.COUNTDOWN, entity_category=EntityCategory.CONFIG, translation_key="countdown", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.COUNTDOWN_SET, entity_category=EntityCategory.CONFIG, translation_key="countdown", ), ), DeviceCategory.QCCDZ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.WORK_MODE, translation_key="charger_work_mode", ), ), DeviceCategory.QN: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LEVEL, translation_key="temperature_level", ), ), DeviceCategory.SD: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.CISTERN, entity_category=EntityCategory.CONFIG, translation_key="vacuum_cistern", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.COLLECTION_MODE, entity_category=EntityCategory.CONFIG, translation_key="vacuum_collection", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.MODE, entity_category=EntityCategory.CONFIG, translation_key="vacuum_mode", @@ -221,116 +228,116 @@ SELECTS: dict[DeviceCategory, tuple[SelectEntityDescription, ...]] = { ), DeviceCategory.SFKZQ: ( # Irrigation will not be run within this set delay period - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.WEATHER_DELAY, translation_key="weather_delay", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.SGBJ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.ALARM_STATE, translation_key="siren_mode", entity_category=EntityCategory.CONFIG, ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.ALARM_VOLUME, translation_key="volume", entity_category=EntityCategory.CONFIG, ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.BRIGHT_STATE, translation_key="brightness", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.SJZ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LEVEL, translation_key="desk_level", entity_category=EntityCategory.CONFIG, ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.UP_DOWN, translation_key="desk_up_down", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.SP: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.IPC_WORK_MODE, entity_category=EntityCategory.CONFIG, translation_key="ipc_work_mode", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.DECIBEL_SENSITIVITY, entity_category=EntityCategory.CONFIG, translation_key="decibel_sensitivity", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.RECORD_MODE, entity_category=EntityCategory.CONFIG, translation_key="record_mode", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.BASIC_NIGHTVISION, entity_category=EntityCategory.CONFIG, translation_key="basic_nightvision", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.BASIC_ANTI_FLICKER, entity_category=EntityCategory.CONFIG, translation_key="basic_anti_flicker", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.MOTION_SENSITIVITY, entity_category=EntityCategory.CONFIG, translation_key="motion_sensitivity", ), ), DeviceCategory.SZJQR: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.MODE, entity_category=EntityCategory.CONFIG, translation_key="fingerbot_mode", ), ), DeviceCategory.TDQ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.RELAY_STATUS, entity_category=EntityCategory.CONFIG, translation_key="relay_status", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LIGHT_MODE, entity_category=EntityCategory.CONFIG, translation_key="light_mode", ), ), DeviceCategory.TGKG: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.RELAY_STATUS, entity_category=EntityCategory.CONFIG, translation_key="relay_status", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LIGHT_MODE, entity_category=EntityCategory.CONFIG, translation_key="light_mode", ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LED_TYPE_1, entity_category=EntityCategory.CONFIG, translation_key="indexed_led_type", translation_placeholders={"index": "1"}, ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LED_TYPE_2, entity_category=EntityCategory.CONFIG, translation_key="indexed_led_type", translation_placeholders={"index": "2"}, ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LED_TYPE_3, entity_category=EntityCategory.CONFIG, translation_key="indexed_led_type", @@ -338,13 +345,13 @@ SELECTS: dict[DeviceCategory, tuple[SelectEntityDescription, ...]] = { ), ), DeviceCategory.TGQ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LED_TYPE_1, entity_category=EntityCategory.CONFIG, translation_key="indexed_led_type", translation_placeholders={"index": "1"}, ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LED_TYPE_2, entity_category=EntityCategory.CONFIG, translation_key="indexed_led_type", @@ -352,19 +359,19 @@ SELECTS: dict[DeviceCategory, tuple[SelectEntityDescription, ...]] = { ), ), DeviceCategory.XNYJCN: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.WORK_MODE, translation_key="inverter_work_mode", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.ZNJDQ: ( - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.RELAY_STATUS, translation_key="relay_status", entity_category=EntityCategory.CONFIG, ), - SelectEntityDescription( + TuyaSelectEntityDescription( key=DPCode.LIGHT_MODE, translation_key="light_mode", entity_category=EntityCategory.CONFIG, @@ -419,7 +426,7 @@ class TuyaSelectEntity(TuyaEntity, SelectEntity): self, device: CustomerDevice, device_manager: Manager, - description: SelectEntityDescription, + description: TuyaSelectEntityDescription, definition: SelectDefinition, ) -> None: """Initialize a Tuya select entity.""" diff --git a/homeassistant/components/tuya/sensor.py b/homeassistant/components/tuya/sensor.py index 665044992913..d4212f1fdd2b 100644 --- a/homeassistant/components/tuya/sensor.py +++ b/homeassistant/components/tuya/sensor.py @@ -59,12 +59,12 @@ from .const import ( DPCode, ) from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription from .util import get_device_temp_unit_convert @dataclass(frozen=True) -class TuyaSensorEntityDescription(SensorEntityDescription): +class TuyaSensorEntityDescription(TuyaEntityDescription, SensorEntityDescription): """Describes Tuya sensor entity.""" dpcode: DPCode | None = None diff --git a/homeassistant/components/tuya/siren.py b/homeassistant/components/tuya/siren.py index e43f4d56fa31..ed06cb477d04 100644 --- a/homeassistant/components/tuya/siren.py +++ b/homeassistant/components/tuya/siren.py @@ -1,5 +1,6 @@ """Support for Tuya siren.""" +from dataclasses import dataclass from typing import Any, override from tuya_device_handlers.definition.siren import ( @@ -20,30 +21,36 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription -SIRENS: dict[DeviceCategory, tuple[SirenEntityDescription, ...]] = { + +@dataclass(frozen=True) +class TuyaSirenEntityDescription(TuyaEntityDescription, SirenEntityDescription): + """Describes a Tuya siren entity.""" + + +SIRENS: dict[DeviceCategory, tuple[TuyaSirenEntityDescription, ...]] = { DeviceCategory.CO2BJ: ( - SirenEntityDescription( + TuyaSirenEntityDescription( key=DPCode.ALARM_SWITCH, entity_category=EntityCategory.CONFIG, translation_key="siren", ), ), DeviceCategory.DGNBJ: ( - SirenEntityDescription( + TuyaSirenEntityDescription( key=DPCode.ALARM_SWITCH, translation_key="siren", ), ), DeviceCategory.SGBJ: ( - SirenEntityDescription( + TuyaSirenEntityDescription( key=DPCode.ALARM_SWITCH, name=None, ), ), DeviceCategory.SP: ( - SirenEntityDescription( + TuyaSirenEntityDescription( key=DPCode.SIREN_SWITCH, translation_key="siren", ), @@ -93,7 +100,7 @@ class TuyaSirenEntity(TuyaEntity, SirenEntity): self, device: CustomerDevice, device_manager: Manager, - description: SirenEntityDescription, + description: TuyaSirenEntityDescription, definition: SirenDefinition, ) -> None: """Init Tuya Siren.""" diff --git a/homeassistant/components/tuya/switch.py b/homeassistant/components/tuya/switch.py index 5d1215f68f55..7264f24023b2 100644 --- a/homeassistant/components/tuya/switch.py +++ b/homeassistant/components/tuya/switch.py @@ -1,5 +1,6 @@ """Support for Tuya switches.""" +from dataclasses import dataclass from typing import Any, override from tuya_device_handlers.definition.switch import ( @@ -20,41 +21,47 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription + # All descriptions can be found here. Mostly the Boolean data types in the # default instruction set of each category end up being a Switch. # https://developer.tuya.com/en/docs/iot/standarddescription?id=K9i5ql6waswzq -SWITCHES: dict[DeviceCategory, tuple[SwitchEntityDescription, ...]] = { +@dataclass(frozen=True) +class TuyaSwitchEntityDescription(TuyaEntityDescription, SwitchEntityDescription): + """Describes a Tuya switch entity.""" + + +SWITCHES: dict[DeviceCategory, tuple[TuyaSwitchEntityDescription, ...]] = { DeviceCategory.BH: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.START, translation_key="start", ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.WARM, translation_key="heat_preservation", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.BZYD: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, name=None, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", icon="mdi:account-lock", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_MUSIC, translation_key="music", icon="mdi:music", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SNOOZE, translation_key="snooze", icon="mdi:alarm-snooze", @@ -62,63 +69,63 @@ SWITCHES: dict[DeviceCategory, tuple[SwitchEntityDescription, ...]] = { ), ), DeviceCategory.CJKG: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_1, translation_key="indexed_switch", translation_placeholders={"index": "1"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_2, translation_key="indexed_switch", translation_placeholders={"index": "2"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_3, translation_key="indexed_switch", translation_placeholders={"index": "3"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_4, translation_key="indexed_switch", translation_placeholders={"index": "4"}, ), ), DeviceCategory.CL: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CONTROL_BACK, translation_key="reverse", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.OPPOSITE, translation_key="reverse", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.CN: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.DISINFECTION, translation_key="disinfection", ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.WATER, translation_key="water", ), ), DeviceCategory.CS: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.ANION, translation_key="ionizer", icon="mdi:atom", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", icon="mdi:account-lock", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.FILTER_RESET, translation_key="filter_reset", icon="mdi:filter", @@ -126,39 +133,39 @@ SWITCHES: dict[DeviceCategory, tuple[SwitchEntityDescription, ...]] = { ), ), DeviceCategory.CWJWQ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="switch", ), ), DeviceCategory.CWWSQ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SLOW_FEED, translation_key="slow_feed", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.CWYSJ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.FILTER_RESET, translation_key="filter_reset", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.PUMP_RESET, translation_key="water_pump_reset", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="power", ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.WATER_RESET, translation_key="reset_of_water_usage_days", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.UV, translation_key="uv_sterilization", entity_category=EntityCategory.CONFIG, @@ -168,54 +175,54 @@ SWITCHES: dict[DeviceCategory, tuple[SwitchEntityDescription, ...]] = { # There are sockets available with an RGB light # that advertise as `dj`, but provide an additional # switch to control the plug. - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="plug", ), ), DeviceCategory.DLQ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="switch", ), ), DeviceCategory.DR: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, name="Power", icon="mdi:power", device_class=SwitchDeviceClass.SWITCH, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_1, name="Side A Power", icon="mdi:alpha-a", device_class=SwitchDeviceClass.SWITCH, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_2, name="Side B Power", icon="mdi:alpha-b", device_class=SwitchDeviceClass.SWITCH, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.PREHEAT, name="Preheat", icon="mdi:radiator", device_class=SwitchDeviceClass.SWITCH, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.PREHEAT_1, name="Side A Preheat", icon="mdi:radiator", device_class=SwitchDeviceClass.SWITCH, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.PREHEAT_2, name="Side B Preheat", icon="mdi:radiator", @@ -223,284 +230,284 @@ SWITCHES: dict[DeviceCategory, tuple[SwitchEntityDescription, ...]] = { ), ), DeviceCategory.FS: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.ANION, translation_key="anion", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.HUMIDIFIER, translation_key="humidification", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.OXYGEN, translation_key="oxygen_bar", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.FAN_COOL, translation_key="natural_wind", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.FAN_BEEP, translation_key="sound", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.FSD: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.FAN_BEEP, translation_key="sound", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.GGQ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_1, translation_key="indexed_switch", translation_placeholders={"index": "1"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_2, translation_key="indexed_switch", translation_placeholders={"index": "2"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_3, translation_key="indexed_switch", translation_placeholders={"index": "3"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_4, translation_key="indexed_switch", translation_placeholders={"index": "4"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_5, translation_key="indexed_switch", translation_placeholders={"index": "5"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_6, translation_key="indexed_switch", translation_placeholders={"index": "6"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_7, translation_key="indexed_switch", translation_placeholders={"index": "7"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_8, translation_key="indexed_switch", translation_placeholders={"index": "8"}, ), ), DeviceCategory.HXD: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_1, translation_key="radio", ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_2, translation_key="indexed_alarm", translation_placeholders={"index": "1"}, entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_3, translation_key="indexed_alarm", translation_placeholders={"index": "2"}, entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_4, translation_key="indexed_alarm", translation_placeholders={"index": "3"}, entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_5, translation_key="indexed_alarm", translation_placeholders={"index": "4"}, entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_6, translation_key="sleep_aid", ), ), DeviceCategory.JSQ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_SOUND, translation_key="voice", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SLEEP, translation_key="sleep", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.STERILIZATION, translation_key="sterilization", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.KG: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_1, translation_key="indexed_switch", translation_placeholders={"index": "1"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_2, translation_key="indexed_switch", translation_placeholders={"index": "2"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_3, translation_key="indexed_switch", translation_placeholders={"index": "3"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_4, translation_key="indexed_switch", translation_placeholders={"index": "4"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_5, translation_key="indexed_switch", translation_placeholders={"index": "5"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_6, translation_key="indexed_switch", translation_placeholders={"index": "6"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_7, translation_key="indexed_switch", translation_placeholders={"index": "7"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_8, translation_key="indexed_switch", translation_placeholders={"index": "8"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB1, translation_key="indexed_usb", translation_placeholders={"index": "1"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB2, translation_key="indexed_usb", translation_placeholders={"index": "2"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB3, translation_key="indexed_usb", translation_placeholders={"index": "3"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB4, translation_key="indexed_usb", translation_placeholders={"index": "4"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB5, translation_key="indexed_usb", translation_placeholders={"index": "5"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB6, translation_key="indexed_usb", translation_placeholders={"index": "6"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="switch", device_class=SwitchDeviceClass.OUTLET, ), ), DeviceCategory.KJ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.ANION, translation_key="ionizer", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.FILTER_RESET, translation_key="filter_cartridge_reset", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.LOCK, translation_key="child_lock", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="power", ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.WET, translation_key="humidification", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.UV, translation_key="uv_sterilization", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.KT: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.ANION, translation_key="ionizer", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.LOCK, translation_key="child_lock", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.KS: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.ANION, translation_key="ionizer", ), ), DeviceCategory.MAL: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_ALARM_SOUND, # This switch is called "Arm Beep" in the official Tuya app translation_key="arm_beep", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_ALARM_LIGHT, # This switch is called "Siren" in the official Tuya app translation_key="siren", @@ -508,305 +515,305 @@ SWITCHES: dict[DeviceCategory, tuple[SwitchEntityDescription, ...]] = { ), ), DeviceCategory.MSP: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.AUTO_CLEAN, translation_key="auto_clean", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.MZJ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="switch", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.START, translation_key="start", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.PC: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_1, translation_key="indexed_socket", translation_placeholders={"index": "1"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_2, translation_key="indexed_socket", translation_placeholders={"index": "2"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_3, translation_key="indexed_socket", translation_placeholders={"index": "3"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_4, translation_key="indexed_socket", translation_placeholders={"index": "4"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_5, translation_key="indexed_socket", translation_placeholders={"index": "5"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_6, translation_key="indexed_socket", translation_placeholders={"index": "6"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB1, translation_key="indexed_usb", translation_placeholders={"index": "1"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB2, translation_key="indexed_usb", translation_placeholders={"index": "2"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB3, translation_key="indexed_usb", translation_placeholders={"index": "3"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB4, translation_key="indexed_usb", translation_placeholders={"index": "4"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB5, translation_key="indexed_usb", translation_placeholders={"index": "5"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_USB6, translation_key="indexed_usb", translation_placeholders={"index": "6"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="socket", device_class=SwitchDeviceClass.OUTLET, ), ), DeviceCategory.QCCDZ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="switch", ), ), DeviceCategory.QJDCZ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_1, translation_key="switch", ), ), DeviceCategory.QN: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.ANION, translation_key="ionizer", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.LOCK, translation_key="child_lock", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.QXJ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="switch", device_class=SwitchDeviceClass.OUTLET, ), ), DeviceCategory.SD: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_DISTURB, translation_key="do_not_disturb", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.VOICE_SWITCH, translation_key="mute_voice", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.SGBJ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.MUFFLING, translation_key="mute", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.SJZ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.SP: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.WIRELESS_BATTERYLOCK, translation_key="battery_lock", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CRY_DETECTION_SWITCH, translation_key="cry_detection", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.DECIBEL_SWITCH, translation_key="sound_detection", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.RECORD_SWITCH, translation_key="video_recording", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.MOTION_RECORD, translation_key="motion_recording", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.BASIC_PRIVATE, translation_key="privacy_mode", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.BASIC_FLIP, translation_key="flip", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.BASIC_OSD, translation_key="time_watermark", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.BASIC_WDR, translation_key="wide_dynamic_range", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.MOTION_TRACKING, translation_key="motion_tracking", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.MOTION_SWITCH, translation_key="motion_alarm", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.MOTION_AREA_SWITCH, translation_key="motion_detection_zone", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.IPC_AUTO_SIREN, translation_key="auto_siren", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.SZ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="power", ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.PUMP, translation_key="pump", ), ), DeviceCategory.SZJQR: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="switch", ), ), DeviceCategory.TDQ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_1, translation_key="indexed_switch", translation_placeholders={"index": "1"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_2, translation_key="indexed_switch", translation_placeholders={"index": "2"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_3, translation_key="indexed_switch", translation_placeholders={"index": "3"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_4, translation_key="indexed_switch", translation_placeholders={"index": "4"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_5, translation_key="indexed_switch", translation_placeholders={"index": "5"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_6, translation_key="indexed_switch", translation_placeholders={"index": "6"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.TYNDJ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_SAVE_ENERGY, translation_key="energy_saving", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.WG2: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.MUFFLING, translation_key="mute", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_KB_SOUND, # Poorly translated as "Key tone switch of host" in the official Tuya app translation_key="keypad_sound", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_ALARM_PROPEL, # Poorly translated as "alarm push switch" in the official Tuya app translation_key="alarm_push_notifications", @@ -814,25 +821,25 @@ SWITCHES: dict[DeviceCategory, tuple[SwitchEntityDescription, ...]] = { ), ), DeviceCategory.WK: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.FROST, translation_key="frost_protection", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.WKCZ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_1, translation_key="indexed_switch", translation_placeholders={"index": "1"}, device_class=SwitchDeviceClass.OUTLET, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_2, translation_key="indexed_switch", translation_placeholders={"index": "2"}, @@ -840,79 +847,79 @@ SWITCHES: dict[DeviceCategory, tuple[SwitchEntityDescription, ...]] = { ), ), DeviceCategory.WKF: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.WINDOW_CHECK, translation_key="open_window_detection", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.WNYKQ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, name=None, ), ), DeviceCategory.WSDCG: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="switch", device_class=SwitchDeviceClass.OUTLET, ), ), DeviceCategory.XDD: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.DO_NOT_DISTURB, translation_key="do_not_disturb", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.XNYJCN: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.FEEDIN_POWER_LIMIT_ENABLE, translation_key="output_power_limit", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.XXJ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="power", ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_SPRAY, translation_key="spray", ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_VOICE, translation_key="voice", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.YWBJ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.MUFFLING, translation_key="mute", entity_category=EntityCategory.CONFIG, ), ), DeviceCategory.ZNDB: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="switch", ), ), DeviceCategory.ZNJDQ: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH_1, translation_key="indexed_switch", translation_placeholders={"index": "1"}, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", icon="mdi:account-lock", @@ -920,19 +927,19 @@ SWITCHES: dict[DeviceCategory, tuple[SwitchEntityDescription, ...]] = { ), ), DeviceCategory.ZNJXS: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="switch", ), ), DeviceCategory.ZNRB: ( - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.CHILD_LOCK, translation_key="child_lock", icon="mdi:account-lock", entity_category=EntityCategory.CONFIG, ), - SwitchEntityDescription( + TuyaSwitchEntityDescription( key=DPCode.SWITCH, translation_key="switch", ), @@ -983,7 +990,7 @@ class TuyaSwitchEntity(TuyaEntity, SwitchEntity): self, device: CustomerDevice, device_manager: Manager, - description: SwitchEntityDescription, + description: TuyaSwitchEntityDescription, definition: SwitchDefinition, ) -> None: """Init TuyaHaSwitch.""" diff --git a/homeassistant/components/tuya/vacuum.py b/homeassistant/components/tuya/vacuum.py index ba75ccce13e7..213825e97b0a 100644 --- a/homeassistant/components/tuya/vacuum.py +++ b/homeassistant/components/tuya/vacuum.py @@ -1,5 +1,6 @@ """Support for Tuya Vacuums.""" +from dataclasses import dataclass from typing import Any, override from tuya_device_handlers.definition.vacuum import ( @@ -24,7 +25,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription _TUYA_TO_HA_ACTIVITY_MAPPINGS = { TuyaVacuumActivity.CLEANING: VacuumActivity.CLEANING, @@ -35,8 +36,14 @@ _TUYA_TO_HA_ACTIVITY_MAPPINGS = { TuyaVacuumActivity.ERROR: VacuumActivity.ERROR, } -VACUUMS: dict[DeviceCategory, StateVacuumEntityDescription] = { - DeviceCategory.SD: StateVacuumEntityDescription(key=""), + +@dataclass(frozen=True) +class TuyaVacuumEntityDescription(TuyaEntityDescription, StateVacuumEntityDescription): + """Describes a Tuya vacuum entity.""" + + +VACUUMS: dict[DeviceCategory, TuyaVacuumEntityDescription] = { + DeviceCategory.SD: TuyaVacuumEntityDescription(key=""), } @@ -78,7 +85,7 @@ class TuyaVacuumEntity(TuyaEntity, StateVacuumEntity): self, device: CustomerDevice, device_manager: Manager, - description: StateVacuumEntityDescription, + description: TuyaVacuumEntityDescription, definition: VacuumDefinition, ) -> None: """Init Tuya vacuum.""" diff --git a/homeassistant/components/tuya/valve.py b/homeassistant/components/tuya/valve.py index 6aa10bb51c99..32fd08d0b224 100644 --- a/homeassistant/components/tuya/valve.py +++ b/homeassistant/components/tuya/valve.py @@ -1,5 +1,6 @@ """Support for Tuya valves.""" +from dataclasses import dataclass from typing import override from tuya_device_handlers.definition.valve import ( @@ -20,58 +21,64 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode from .coordinator import TuyaConfigEntry -from .entity import TuyaEntity +from .entity import TuyaEntity, TuyaEntityDescription -VALVES: dict[DeviceCategory, tuple[ValveEntityDescription, ...]] = { + +@dataclass(frozen=True) +class TuyaValveEntityDescription(TuyaEntityDescription, ValveEntityDescription): + """Describes a Tuya valve entity.""" + + +VALVES: dict[DeviceCategory, tuple[TuyaValveEntityDescription, ...]] = { DeviceCategory.SFKZQ: ( - ValveEntityDescription( + TuyaValveEntityDescription( key=DPCode.SWITCH, translation_key="valve", device_class=ValveDeviceClass.WATER, ), - ValveEntityDescription( + TuyaValveEntityDescription( key=DPCode.SWITCH_1, translation_key="indexed_valve", translation_placeholders={"index": "1"}, device_class=ValveDeviceClass.WATER, ), - ValveEntityDescription( + TuyaValveEntityDescription( key=DPCode.SWITCH_2, translation_key="indexed_valve", translation_placeholders={"index": "2"}, device_class=ValveDeviceClass.WATER, ), - ValveEntityDescription( + TuyaValveEntityDescription( key=DPCode.SWITCH_3, translation_key="indexed_valve", translation_placeholders={"index": "3"}, device_class=ValveDeviceClass.WATER, ), - ValveEntityDescription( + TuyaValveEntityDescription( key=DPCode.SWITCH_4, translation_key="indexed_valve", translation_placeholders={"index": "4"}, device_class=ValveDeviceClass.WATER, ), - ValveEntityDescription( + TuyaValveEntityDescription( key=DPCode.SWITCH_5, translation_key="indexed_valve", translation_placeholders={"index": "5"}, device_class=ValveDeviceClass.WATER, ), - ValveEntityDescription( + TuyaValveEntityDescription( key=DPCode.SWITCH_6, translation_key="indexed_valve", translation_placeholders={"index": "6"}, device_class=ValveDeviceClass.WATER, ), - ValveEntityDescription( + TuyaValveEntityDescription( key=DPCode.SWITCH_7, translation_key="indexed_valve", translation_placeholders={"index": "7"}, device_class=ValveDeviceClass.WATER, ), - ValveEntityDescription( + TuyaValveEntityDescription( key=DPCode.SWITCH_8, translation_key="indexed_valve", translation_placeholders={"index": "8"}, @@ -120,7 +127,7 @@ class TuyaValveEntity(TuyaEntity, ValveEntity): self, device: CustomerDevice, device_manager: Manager, - description: ValveEntityDescription, + description: TuyaValveEntityDescription, definition: ValveDefinition, ) -> None: """Init TuyaValveEntity."""