From f7fcf02e5037e82ed1eddb0803efe713b9a1c498 Mon Sep 17 00:00:00 2001 From: xZetsubou Date: Sun, 12 May 2024 05:15:00 +0300 Subject: [PATCH] add supports for locks (not tested) --- custom_components/localtuya/const.py | 5 ++ .../localtuya/core/ha_entities/__init__.py | 2 + .../localtuya/core/ha_entities/base.py | 3 + .../localtuya/core/ha_entities/sensors.py | 8 +++ custom_components/localtuya/lock.py | 64 +++++++++++++++++++ .../localtuya/translations/en.json | 4 +- 6 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 custom_components/localtuya/lock.py diff --git a/custom_components/localtuya/const.py b/custom_components/localtuya/const.py index 7c98cf1cf..672a9a45d 100644 --- a/custom_components/localtuya/const.py +++ b/custom_components/localtuya/const.py @@ -30,6 +30,7 @@ "Fan": Platform.FAN, "Humidifier": Platform.HUMIDIFIER, "Light": Platform.LIGHT, + "Lock": Platform.LOCK, "Number": Platform.NUMBER, "Remote": Platform.REMOTE, "Select": Platform.SELECT, @@ -177,6 +178,10 @@ CONF_RECEIVE_DP = "receive_dp" CONF_KEY_STUDY_DP = "key_study_dp" +# Lock +CONF_JAMMED_DP = "jammed_dp" +CONF_LOCK_STATE_DP = "lock_state_dp" + # States ATTR_STATE = "raw_state" CONF_RESTORE_ON_RECONNECT = "restore_on_reconnect" diff --git a/custom_components/localtuya/core/ha_entities/__init__.py b/custom_components/localtuya/core/ha_entities/__init__.py index fa563dad2..381bb3e83 100644 --- a/custom_components/localtuya/core/ha_entities/__init__.py +++ b/custom_components/localtuya/core/ha_entities/__init__.py @@ -47,6 +47,7 @@ from .sirens import SIRENS from .switches import SWITCHES from .vacuums import VACUUMS +from .locks import LOCKS # The supported PLATFORMS [ Platform: Data ] DATA_PLATFORMS = { @@ -58,6 +59,7 @@ Platform.FAN: FANS, Platform.HUMIDIFIER: HUMIDIFIERS, Platform.LIGHT: LIGHTS, + Platform.LOCK: LOCKS, Platform.NUMBER: NUMBERS, Platform.REMOTE: REMOTES, Platform.SELECT: SELECTS, diff --git a/custom_components/localtuya/core/ha_entities/base.py b/custom_components/localtuya/core/ha_entities/base.py index 9b0095a1e..c79f19a94 100644 --- a/custom_components/localtuya/core/ha_entities/base.py +++ b/custom_components/localtuya/core/ha_entities/base.py @@ -326,6 +326,7 @@ class DPCode(StrEnum): LIGHT_MODE = "light_mode" LOADSTATUS = "loadstatus" LOCK = "lock" # Lock / Child lock + LOCK_MOTOR_STATE = "lock_motor_state" LOWER_TEMP = "lower_temp" LOWER_TEMP_F = "lower_temp_f" LOWPROTECTVALUE = "lowprotectvalue" @@ -367,6 +368,7 @@ class DPCode(StrEnum): NET_STATE = "net_state" NORMAL_OPEN_SWITCH = "normal_open_switch" ODU_FAN_SPEED = "odu_fan_speed" + OPEN_CLOSE = "open_close" OPPOSITE = "opposite" OPTIMUMSTART = "optimumstart" OTHEREVENT = "OtherEvent" @@ -438,6 +440,7 @@ class DPCode(StrEnum): RELAY_STATUS_8 = "relay_status_8" # Scene Switch cjkg REMAIN_TIME = "remain_time" REMOTE_REGISTER = "remote_register" + REMOTE_UNLOCK_SWITCH = "remote_unlock_switch" REPORT_PERIOD_SET = "report_period_set" REPORT_RATE_CONTROL = "report_rate_control" RESET_DUSTER_CLOTH = "reset_duster_cloth" diff --git a/custom_components/localtuya/core/ha_entities/sensors.py b/custom_components/localtuya/core/ha_entities/sensors.py index 6777ef266..8492b9c62 100644 --- a/custom_components/localtuya/core/ha_entities/sensors.py +++ b/custom_components/localtuya/core/ha_entities/sensors.py @@ -1400,6 +1400,14 @@ def localtuya_sensor(unit_of_measurement=None, scale_factor: float = 1) -> dict: entity_category=EntityCategory.DIAGNOSTIC, ), ), + # Lock + "ms": ( + LocalTuyaEntity( + id=DPCode.LOCK_MOTOR_STATE, + name="Motor State", + entity_category=EntityCategory.DIAGNOSTIC, + ), + ), # Smart Water Meter # https://developer.tuya.com/en/docs/iot/f?id=Ka8n052xu7w4c "znsb": ( diff --git a/custom_components/localtuya/lock.py b/custom_components/localtuya/lock.py new file mode 100644 index 000000000..f25035c48 --- /dev/null +++ b/custom_components/localtuya/lock.py @@ -0,0 +1,64 @@ +"""Platform to present any Tuya DP as a Lock.""" + +import logging +from functools import partial +from typing import Any +from .config_flow import _col_to_select + +import voluptuous as vol +from homeassistant.components.lock import DOMAIN, LockEntity +from .entity import LocalTuyaEntity, async_setup_entry + +from .const import CONF_JAMMED_DP, CONF_LOCK_STATE_DP + +_LOGGER = logging.getLogger(__name__) + + +def flow_schema(dps): + """Return schema used in config flow.""" + return { + vol.Optional(CONF_LOCK_STATE_DP): _col_to_select(dps, is_dps=True), + vol.Optional(CONF_JAMMED_DP): _col_to_select(dps, is_dps=True), + } + + +class LocalTuyaLock(LocalTuyaEntity, LockEntity): + """Representation of a Tuya Lock.""" + + def __init__( + self, + device, + config_entry, + Lockid, + **kwargs, + ): + """Initialize the Tuya Lock.""" + super().__init__(device, config_entry, Lockid, _LOGGER, **kwargs) + self._state = None + + async def async_lock(self, **kwargs: Any) -> None: + """Lock the lock.""" + await self._device.set_dp(True, self._dp_id) + + async def async_unlock(self, **kwargs: Any) -> None: + """Unlock the lock.""" + await self._device.set_dp(False, self._dp_id) + + def status_updated(self): + """Device status was updated.""" + state = self.dp_value(self._dp_id) + if (lock_state := self.dp_value(CONF_LOCK_STATE_DP)) or lock_state is not None: + state = lock_state + + self._attr_is_locked = state not in (False, "closed", "close", None) + + if jammed := self.dp_value(CONF_JAMMED_DP, False): + self._attr_is_jammed = jammed + + # No need to restore state for a Lock + async def restore_state_when_connected(self): + """Do nothing for a Lock.""" + return + + +async_setup_entry = partial(async_setup_entry, DOMAIN, LocalTuyaLock, flow_schema) diff --git a/custom_components/localtuya/translations/en.json b/custom_components/localtuya/translations/en.json index e4a1c7ef6..766302e7c 100644 --- a/custom_components/localtuya/translations/en.json +++ b/custom_components/localtuya/translations/en.json @@ -240,7 +240,9 @@ "max_humidity": "Set the maximum supported humidity", "alarm_supported_states": "States supported by the device", "receive_dp":"Receiving signals DP. (default is 202)", - "key_study_dp":"(Optional) Key Study DP (usually 7)" + "key_study_dp":"(Optional) Key Study DP (usually 7)", + "lock_state_dp":"(Optional) Lock state DP", + "jammed_dp":"(Optional) Jam DP" }, "data_description": { "hvac_mode_set":"Each line represents [ hvac_mode: device_value ] [Supported HVAC Modes](https://developers.home-assistant.io/docs/core/entity/climate/#hvac-modes)",