mirror of
https://github.com/home-assistant/core.git
synced 2026-09-26 17:31:15 -04:00
Add a common base class for Tuya entity descriptions (#182283)
This commit is contained in:
@@ -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."""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)})
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."""
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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."""
|
||||
|
||||
@@ -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."""
|
||||
|
||||
Reference in New Issue
Block a user