mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Replace all Tuya device property constants with an Enum (#57559)
This commit is contained in:
parent
c55e9136ee
commit
a4357fdb95
@ -29,33 +29,10 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
|
|
||||||
from . import HomeAssistantTuyaData
|
from . import HomeAssistantTuyaData
|
||||||
from .base import TuyaHaEntity
|
from .base import TuyaHaEntity
|
||||||
from .const import DOMAIN, TUYA_DISCOVERY_NEW
|
from .const import DOMAIN, TUYA_DISCOVERY_NEW, DPCode
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# Air Conditioner
|
|
||||||
# https://developer.tuya.com/en/docs/iot/f?id=K9gf46qujdmwb
|
|
||||||
DPCODE_SWITCH = "switch"
|
|
||||||
DPCODE_TEMP_SET = "temp_set"
|
|
||||||
DPCODE_TEMP_SET_F = "temp_set_f"
|
|
||||||
DPCODE_MODE = "mode"
|
|
||||||
DPCODE_HUMIDITY_SET = "humidity_set"
|
|
||||||
DPCODE_FAN_SPEED_ENUM = "fan_speed_enum"
|
|
||||||
|
|
||||||
# Temperature unit
|
|
||||||
DPCODE_TEMP_UNIT_CONVERT = "temp_unit_convert"
|
|
||||||
DPCODE_C_F = "c_f"
|
|
||||||
|
|
||||||
# swing flap switch
|
|
||||||
DPCODE_SWITCH_HORIZONTAL = "switch_horizontal"
|
|
||||||
DPCODE_SWITCH_VERTICAL = "switch_vertical"
|
|
||||||
|
|
||||||
# status
|
|
||||||
DPCODE_TEMP_CURRENT = "temp_current"
|
|
||||||
DPCODE_TEMP_CURRENT_F = "temp_current_f"
|
|
||||||
DPCODE_HUMIDITY_CURRENT = "humidity_current"
|
|
||||||
|
|
||||||
SWING_OFF = "swing_off"
|
SWING_OFF = "swing_off"
|
||||||
SWING_VERTICAL = "swing_vertical"
|
SWING_VERTICAL = "swing_vertical"
|
||||||
SWING_HORIZONTAL = "swing_horizontal"
|
SWING_HORIZONTAL = "swing_horizontal"
|
||||||
@ -72,6 +49,7 @@ TUYA_HVAC_TO_HA = {
|
|||||||
"auto": HVAC_MODE_AUTO,
|
"auto": HVAC_MODE_AUTO,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# https://developer.tuya.com/en/docs/iot/standarddescription?id=K9i5ql6waswzq
|
||||||
TUYA_SUPPORT_TYPE = {
|
TUYA_SUPPORT_TYPE = {
|
||||||
"kt", # Air conditioner
|
"kt", # Air conditioner
|
||||||
"qn", # Heater
|
"qn", # Heater
|
||||||
@ -108,14 +86,14 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
def __init__(self, device: TuyaDevice, device_manager: TuyaDeviceManager) -> None:
|
def __init__(self, device: TuyaDevice, device_manager: TuyaDeviceManager) -> None:
|
||||||
"""Init Tuya Ha Climate."""
|
"""Init Tuya Ha Climate."""
|
||||||
super().__init__(device, device_manager)
|
super().__init__(device, device_manager)
|
||||||
if DPCODE_C_F in self.tuya_device.status:
|
if DPCode.C_F in self.tuya_device.status:
|
||||||
self.dp_temp_unit = DPCODE_C_F
|
self.dp_temp_unit = DPCode.C_F
|
||||||
else:
|
else:
|
||||||
self.dp_temp_unit = DPCODE_TEMP_UNIT_CONVERT
|
self.dp_temp_unit = DPCode.TEMP_UNIT_CONVERT
|
||||||
|
|
||||||
def get_temp_set_scale(self) -> int | None:
|
def get_temp_set_scale(self) -> int | None:
|
||||||
"""Get temperature set scale."""
|
"""Get temperature set scale."""
|
||||||
dp_temp_set = DPCODE_TEMP_SET if self.is_celsius() else DPCODE_TEMP_SET_F
|
dp_temp_set = DPCode.TEMP_SET if self.is_celsius() else DPCode.TEMP_SET_F
|
||||||
temp_set_value_range_item = self.tuya_device.status_range.get(dp_temp_set)
|
temp_set_value_range_item = self.tuya_device.status_range.get(dp_temp_set)
|
||||||
if not temp_set_value_range_item:
|
if not temp_set_value_range_item:
|
||||||
return None
|
return None
|
||||||
@ -126,7 +104,7 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
def get_temp_current_scale(self) -> int | None:
|
def get_temp_current_scale(self) -> int | None:
|
||||||
"""Get temperature current scale."""
|
"""Get temperature current scale."""
|
||||||
dp_temp_current = (
|
dp_temp_current = (
|
||||||
DPCODE_TEMP_CURRENT if self.is_celsius() else DPCODE_TEMP_CURRENT_F
|
DPCode.TEMP_CURRENT if self.is_celsius() else DPCode.TEMP_CURRENT_F
|
||||||
)
|
)
|
||||||
temp_current_value_range_item = self.tuya_device.status_range.get(
|
temp_current_value_range_item = self.tuya_device.status_range.get(
|
||||||
dp_temp_current
|
dp_temp_current
|
||||||
@ -143,46 +121,46 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
"""Set new target hvac mode."""
|
"""Set new target hvac mode."""
|
||||||
commands = []
|
commands = []
|
||||||
if hvac_mode == HVAC_MODE_OFF:
|
if hvac_mode == HVAC_MODE_OFF:
|
||||||
commands.append({"code": DPCODE_SWITCH, "value": False})
|
commands.append({"code": DPCode.SWITCH, "value": False})
|
||||||
else:
|
else:
|
||||||
commands.append({"code": DPCODE_SWITCH, "value": True})
|
commands.append({"code": DPCode.SWITCH, "value": True})
|
||||||
|
|
||||||
for tuya_mode, ha_mode in TUYA_HVAC_TO_HA.items():
|
for tuya_mode, ha_mode in TUYA_HVAC_TO_HA.items():
|
||||||
if ha_mode == hvac_mode:
|
if ha_mode == hvac_mode:
|
||||||
commands.append({"code": DPCODE_MODE, "value": tuya_mode})
|
commands.append({"code": DPCode.MODE, "value": tuya_mode})
|
||||||
break
|
break
|
||||||
|
|
||||||
self._send_command(commands)
|
self._send_command(commands)
|
||||||
|
|
||||||
def set_fan_mode(self, fan_mode: str) -> None:
|
def set_fan_mode(self, fan_mode: str) -> None:
|
||||||
"""Set new target fan mode."""
|
"""Set new target fan mode."""
|
||||||
self._send_command([{"code": DPCODE_FAN_SPEED_ENUM, "value": fan_mode}])
|
self._send_command([{"code": DPCode.FAN_SPEED_ENUM, "value": fan_mode}])
|
||||||
|
|
||||||
def set_humidity(self, humidity: float) -> None:
|
def set_humidity(self, humidity: float) -> None:
|
||||||
"""Set new target humidity."""
|
"""Set new target humidity."""
|
||||||
self._send_command([{"code": DPCODE_HUMIDITY_SET, "value": int(humidity)}])
|
self._send_command([{"code": DPCode.HUMIDITY_SET, "value": int(humidity)}])
|
||||||
|
|
||||||
def set_swing_mode(self, swing_mode: str) -> None:
|
def set_swing_mode(self, swing_mode: str) -> None:
|
||||||
"""Set new target swing operation."""
|
"""Set new target swing operation."""
|
||||||
if swing_mode == SWING_BOTH:
|
if swing_mode == SWING_BOTH:
|
||||||
commands = [
|
commands = [
|
||||||
{"code": DPCODE_SWITCH_VERTICAL, "value": True},
|
{"code": DPCode.SWITCH_VERTICAL, "value": True},
|
||||||
{"code": DPCODE_SWITCH_HORIZONTAL, "value": True},
|
{"code": DPCode.SWITCH_HORIZONTAL, "value": True},
|
||||||
]
|
]
|
||||||
elif swing_mode == SWING_HORIZONTAL:
|
elif swing_mode == SWING_HORIZONTAL:
|
||||||
commands = [
|
commands = [
|
||||||
{"code": DPCODE_SWITCH_VERTICAL, "value": False},
|
{"code": DPCode.SWITCH_VERTICAL, "value": False},
|
||||||
{"code": DPCODE_SWITCH_HORIZONTAL, "value": True},
|
{"code": DPCode.SWITCH_HORIZONTAL, "value": True},
|
||||||
]
|
]
|
||||||
elif swing_mode == SWING_VERTICAL:
|
elif swing_mode == SWING_VERTICAL:
|
||||||
commands = [
|
commands = [
|
||||||
{"code": DPCODE_SWITCH_VERTICAL, "value": True},
|
{"code": DPCode.SWITCH_VERTICAL, "value": True},
|
||||||
{"code": DPCODE_SWITCH_HORIZONTAL, "value": False},
|
{"code": DPCode.SWITCH_HORIZONTAL, "value": False},
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
commands = [
|
commands = [
|
||||||
{"code": DPCODE_SWITCH_VERTICAL, "value": False},
|
{"code": DPCode.SWITCH_VERTICAL, "value": False},
|
||||||
{"code": DPCODE_SWITCH_HORIZONTAL, "value": False},
|
{"code": DPCode.SWITCH_HORIZONTAL, "value": False},
|
||||||
]
|
]
|
||||||
|
|
||||||
self._send_command(commands)
|
self._send_command(commands)
|
||||||
@ -190,7 +168,7 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
def set_temperature(self, **kwargs: Any) -> None:
|
def set_temperature(self, **kwargs: Any) -> None:
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
_LOGGER.debug("climate temp-> %s", kwargs)
|
_LOGGER.debug("climate temp-> %s", kwargs)
|
||||||
code = DPCODE_TEMP_SET if self.is_celsius() else DPCODE_TEMP_SET_F
|
code = DPCode.TEMP_SET if self.is_celsius() else DPCode.TEMP_SET_F
|
||||||
temp_set_scale = self.get_temp_set_scale()
|
temp_set_scale = self.get_temp_set_scale()
|
||||||
if not temp_set_scale:
|
if not temp_set_scale:
|
||||||
return
|
return
|
||||||
@ -212,8 +190,8 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
if (
|
if (
|
||||||
DPCODE_TEMP_SET in self.tuya_device.status
|
DPCode.TEMP_SET in self.tuya_device.status
|
||||||
or DPCODE_TEMP_CURRENT in self.tuya_device.status
|
or DPCode.TEMP_CURRENT in self.tuya_device.status
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
@ -229,8 +207,8 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
def current_temperature(self) -> float | None:
|
def current_temperature(self) -> float | None:
|
||||||
"""Return the current temperature."""
|
"""Return the current temperature."""
|
||||||
if (
|
if (
|
||||||
DPCODE_TEMP_CURRENT not in self.tuya_device.status
|
DPCode.TEMP_CURRENT not in self.tuya_device.status
|
||||||
and DPCODE_TEMP_CURRENT_F not in self.tuya_device.status
|
and DPCode.TEMP_CURRENT_F not in self.tuya_device.status
|
||||||
):
|
):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -239,12 +217,12 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
if self.is_celsius():
|
if self.is_celsius():
|
||||||
temperature = self.tuya_device.status.get(DPCODE_TEMP_CURRENT)
|
temperature = self.tuya_device.status.get(DPCode.TEMP_CURRENT)
|
||||||
if not temperature:
|
if not temperature:
|
||||||
return None
|
return None
|
||||||
return temperature * 1.0 / (10 ** temp_current_scale)
|
return temperature * 1.0 / (10 ** temp_current_scale)
|
||||||
|
|
||||||
temperature = self.tuya_device.status.get(DPCODE_TEMP_CURRENT_F)
|
temperature = self.tuya_device.status.get(DPCode.TEMP_CURRENT_F)
|
||||||
if not temperature:
|
if not temperature:
|
||||||
return None
|
return None
|
||||||
return temperature * 1.0 / (10 ** temp_current_scale)
|
return temperature * 1.0 / (10 ** temp_current_scale)
|
||||||
@ -252,7 +230,7 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
@property
|
@property
|
||||||
def current_humidity(self) -> int:
|
def current_humidity(self) -> int:
|
||||||
"""Return the current humidity."""
|
"""Return the current humidity."""
|
||||||
return int(self.tuya_device.status.get(DPCODE_HUMIDITY_CURRENT, 0))
|
return int(self.tuya_device.status.get(DPCode.HUMIDITY_CURRENT, 0))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def target_temperature(self) -> float | None:
|
def target_temperature(self) -> float | None:
|
||||||
@ -261,7 +239,7 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
if temp_set_scale is None:
|
if temp_set_scale is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
dpcode_temp_set = self.tuya_device.status.get(DPCODE_TEMP_SET)
|
dpcode_temp_set = self.tuya_device.status.get(DPCode.TEMP_SET)
|
||||||
if dpcode_temp_set is None:
|
if dpcode_temp_set is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -275,10 +253,10 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
return DEFAULT_MAX_TEMP
|
return DEFAULT_MAX_TEMP
|
||||||
|
|
||||||
if self.is_celsius():
|
if self.is_celsius():
|
||||||
if DPCODE_TEMP_SET not in self.tuya_device.function:
|
if DPCode.TEMP_SET not in self.tuya_device.function:
|
||||||
return DEFAULT_MAX_TEMP
|
return DEFAULT_MAX_TEMP
|
||||||
|
|
||||||
function_item = self.tuya_device.function.get(DPCODE_TEMP_SET)
|
function_item = self.tuya_device.function.get(DPCode.TEMP_SET)
|
||||||
if function_item is None:
|
if function_item is None:
|
||||||
return DEFAULT_MAX_TEMP
|
return DEFAULT_MAX_TEMP
|
||||||
|
|
||||||
@ -288,10 +266,10 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
if temp_max is None:
|
if temp_max is None:
|
||||||
return DEFAULT_MAX_TEMP
|
return DEFAULT_MAX_TEMP
|
||||||
return temp_max * 1.0 / (10 ** scale)
|
return temp_max * 1.0 / (10 ** scale)
|
||||||
if DPCODE_TEMP_SET_F not in self.tuya_device.function:
|
if DPCode.TEMP_SET_F not in self.tuya_device.function:
|
||||||
return DEFAULT_MAX_TEMP
|
return DEFAULT_MAX_TEMP
|
||||||
|
|
||||||
function_item_f = self.tuya_device.function.get(DPCODE_TEMP_SET_F)
|
function_item_f = self.tuya_device.function.get(DPCode.TEMP_SET_F)
|
||||||
if function_item_f is None:
|
if function_item_f is None:
|
||||||
return DEFAULT_MAX_TEMP
|
return DEFAULT_MAX_TEMP
|
||||||
|
|
||||||
@ -310,10 +288,10 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
return DEFAULT_MIN_TEMP
|
return DEFAULT_MIN_TEMP
|
||||||
|
|
||||||
if self.is_celsius():
|
if self.is_celsius():
|
||||||
if DPCODE_TEMP_SET not in self.tuya_device.function:
|
if DPCode.TEMP_SET not in self.tuya_device.function:
|
||||||
return DEFAULT_MIN_TEMP
|
return DEFAULT_MIN_TEMP
|
||||||
|
|
||||||
function_temp_item = self.tuya_device.function.get(DPCODE_TEMP_SET)
|
function_temp_item = self.tuya_device.function.get(DPCode.TEMP_SET)
|
||||||
if function_temp_item is None:
|
if function_temp_item is None:
|
||||||
return DEFAULT_MIN_TEMP
|
return DEFAULT_MIN_TEMP
|
||||||
temp_value = json.loads(function_temp_item.values)
|
temp_value = json.loads(function_temp_item.values)
|
||||||
@ -322,10 +300,10 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
return DEFAULT_MIN_TEMP
|
return DEFAULT_MIN_TEMP
|
||||||
return temp_min * 1.0 / (10 ** temp_set_scal)
|
return temp_min * 1.0 / (10 ** temp_set_scal)
|
||||||
|
|
||||||
if DPCODE_TEMP_SET_F not in self.tuya_device.function:
|
if DPCode.TEMP_SET_F not in self.tuya_device.function:
|
||||||
return DEFAULT_MIN_TEMP
|
return DEFAULT_MIN_TEMP
|
||||||
|
|
||||||
temp_value_temp_f = self.tuya_device.function.get(DPCODE_TEMP_SET_F)
|
temp_value_temp_f = self.tuya_device.function.get(DPCode.TEMP_SET_F)
|
||||||
if temp_value_temp_f is None:
|
if temp_value_temp_f is None:
|
||||||
return DEFAULT_MIN_TEMP
|
return DEFAULT_MIN_TEMP
|
||||||
temp_value_f = json.loads(temp_value_temp_f.values)
|
temp_value_f = json.loads(temp_value_temp_f.values)
|
||||||
@ -340,13 +318,13 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
def target_temperature_step(self) -> float | None:
|
def target_temperature_step(self) -> float | None:
|
||||||
"""Return target temperature setp."""
|
"""Return target temperature setp."""
|
||||||
if (
|
if (
|
||||||
DPCODE_TEMP_SET not in self.tuya_device.status_range
|
DPCode.TEMP_SET not in self.tuya_device.status_range
|
||||||
and DPCODE_TEMP_SET_F not in self.tuya_device.status_range
|
and DPCode.TEMP_SET_F not in self.tuya_device.status_range
|
||||||
):
|
):
|
||||||
return 1.0
|
return 1.0
|
||||||
temp_set_value_range = json.loads(
|
temp_set_value_range = json.loads(
|
||||||
self.tuya_device.status_range.get(
|
self.tuya_device.status_range.get(
|
||||||
DPCODE_TEMP_SET if self.is_celsius() else DPCODE_TEMP_SET_F
|
DPCode.TEMP_SET if self.is_celsius() else DPCode.TEMP_SET_F
|
||||||
).values
|
).values
|
||||||
)
|
)
|
||||||
step = temp_set_value_range.get("step")
|
step = temp_set_value_range.get("step")
|
||||||
@ -362,25 +340,25 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
@property
|
@property
|
||||||
def target_humidity(self) -> int:
|
def target_humidity(self) -> int:
|
||||||
"""Return target humidity."""
|
"""Return target humidity."""
|
||||||
return int(self.tuya_device.status.get(DPCODE_HUMIDITY_SET, 0))
|
return int(self.tuya_device.status.get(DPCode.HUMIDITY_SET, 0))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hvac_mode(self) -> str:
|
def hvac_mode(self) -> str:
|
||||||
"""Return hvac mode."""
|
"""Return hvac mode."""
|
||||||
if not self.tuya_device.status.get(DPCODE_SWITCH, False):
|
if not self.tuya_device.status.get(DPCode.SWITCH, False):
|
||||||
return HVAC_MODE_OFF
|
return HVAC_MODE_OFF
|
||||||
if DPCODE_MODE not in self.tuya_device.status:
|
if DPCode.MODE not in self.tuya_device.status:
|
||||||
return HVAC_MODE_OFF
|
return HVAC_MODE_OFF
|
||||||
if self.tuya_device.status.get(DPCODE_MODE) is not None:
|
if self.tuya_device.status.get(DPCode.MODE) is not None:
|
||||||
return TUYA_HVAC_TO_HA[self.tuya_device.status[DPCODE_MODE]]
|
return TUYA_HVAC_TO_HA[self.tuya_device.status[DPCode.MODE]]
|
||||||
return HVAC_MODE_OFF
|
return HVAC_MODE_OFF
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hvac_modes(self) -> list[str]:
|
def hvac_modes(self) -> list[str]:
|
||||||
"""Return hvac modes for select."""
|
"""Return hvac modes for select."""
|
||||||
if DPCODE_MODE not in self.tuya_device.function:
|
if DPCode.MODE not in self.tuya_device.function:
|
||||||
return []
|
return []
|
||||||
modes = json.loads(self.tuya_device.function.get(DPCODE_MODE, {}).values).get(
|
modes = json.loads(self.tuya_device.function.get(DPCode.MODE, {}).values).get(
|
||||||
"range"
|
"range"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -394,12 +372,12 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
@property
|
@property
|
||||||
def fan_mode(self) -> str | None:
|
def fan_mode(self) -> str | None:
|
||||||
"""Return fan mode."""
|
"""Return fan mode."""
|
||||||
return self.tuya_device.status.get(DPCODE_FAN_SPEED_ENUM)
|
return self.tuya_device.status.get(DPCode.FAN_SPEED_ENUM)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fan_modes(self) -> list[str]:
|
def fan_modes(self) -> list[str]:
|
||||||
"""Return fan modes for select."""
|
"""Return fan modes for select."""
|
||||||
fan_speed_device_function = self.tuya_device.function.get(DPCODE_FAN_SPEED_ENUM)
|
fan_speed_device_function = self.tuya_device.function.get(DPCode.FAN_SPEED_ENUM)
|
||||||
if not fan_speed_device_function:
|
if not fan_speed_device_function:
|
||||||
return []
|
return []
|
||||||
return json.loads(fan_speed_device_function.values).get("range", [])
|
return json.loads(fan_speed_device_function.values).get("range", [])
|
||||||
@ -409,13 +387,13 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
"""Return swing mode."""
|
"""Return swing mode."""
|
||||||
mode = 0
|
mode = 0
|
||||||
if (
|
if (
|
||||||
DPCODE_SWITCH_HORIZONTAL in self.tuya_device.status
|
DPCode.SWITCH_HORIZONTAL in self.tuya_device.status
|
||||||
and self.tuya_device.status.get(DPCODE_SWITCH_HORIZONTAL)
|
and self.tuya_device.status.get(DPCode.SWITCH_HORIZONTAL)
|
||||||
):
|
):
|
||||||
mode += 1
|
mode += 1
|
||||||
if (
|
if (
|
||||||
DPCODE_SWITCH_VERTICAL in self.tuya_device.status
|
DPCode.SWITCH_VERTICAL in self.tuya_device.status
|
||||||
and self.tuya_device.status.get(DPCODE_SWITCH_VERTICAL)
|
and self.tuya_device.status.get(DPCode.SWITCH_VERTICAL)
|
||||||
):
|
):
|
||||||
mode += 2
|
mode += 2
|
||||||
|
|
||||||
@ -437,17 +415,17 @@ class TuyaHaClimate(TuyaHaEntity, ClimateEntity):
|
|||||||
"""Flag supported features."""
|
"""Flag supported features."""
|
||||||
supports = 0
|
supports = 0
|
||||||
if (
|
if (
|
||||||
DPCODE_TEMP_SET in self.tuya_device.status
|
DPCode.TEMP_SET in self.tuya_device.status
|
||||||
or DPCODE_TEMP_SET_F in self.tuya_device.status
|
or DPCode.TEMP_SET_F in self.tuya_device.status
|
||||||
):
|
):
|
||||||
supports |= SUPPORT_TARGET_TEMPERATURE
|
supports |= SUPPORT_TARGET_TEMPERATURE
|
||||||
if DPCODE_FAN_SPEED_ENUM in self.tuya_device.status:
|
if DPCode.FAN_SPEED_ENUM in self.tuya_device.status:
|
||||||
supports |= SUPPORT_FAN_MODE
|
supports |= SUPPORT_FAN_MODE
|
||||||
if DPCODE_HUMIDITY_SET in self.tuya_device.status:
|
if DPCode.HUMIDITY_SET in self.tuya_device.status:
|
||||||
supports |= SUPPORT_TARGET_HUMIDITY
|
supports |= SUPPORT_TARGET_HUMIDITY
|
||||||
if (
|
if (
|
||||||
DPCODE_SWITCH_HORIZONTAL in self.tuya_device.status
|
DPCode.SWITCH_HORIZONTAL in self.tuya_device.status
|
||||||
or DPCODE_SWITCH_VERTICAL in self.tuya_device.status
|
or DPCode.SWITCH_VERTICAL in self.tuya_device.status
|
||||||
):
|
):
|
||||||
supports |= SUPPORT_SWING_MODE
|
supports |= SUPPORT_SWING_MODE
|
||||||
return supports
|
return supports
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"""Constants for the Tuya integration."""
|
"""Constants for the Tuya integration."""
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
from tuya_iot import TuyaCloudOpenAPIEndpoint
|
from tuya_iot import TuyaCloudOpenAPIEndpoint
|
||||||
|
|
||||||
@ -54,6 +55,45 @@ SMARTLIFE_APP = "smartlife"
|
|||||||
PLATFORMS = ["climate", "fan", "light", "scene", "switch"]
|
PLATFORMS = ["climate", "fan", "light", "scene", "switch"]
|
||||||
|
|
||||||
|
|
||||||
|
class DPCode(str, Enum):
|
||||||
|
"""Device Property Codes used by Tuya.
|
||||||
|
|
||||||
|
https://developer.tuya.com/en/docs/iot/standarddescription?id=K9i5ql6waswzq
|
||||||
|
"""
|
||||||
|
|
||||||
|
ANION = "anion" # Ionizer unit
|
||||||
|
BRIGHT_VALUE = "bright_value" # Brightness
|
||||||
|
C_F = "c_f" # Temperature unit switching
|
||||||
|
COLOUR_DATA = "colour_data" # Colored light mode
|
||||||
|
COLOUR_DATA_V2 = "colour_data_v2" # Colored light mode
|
||||||
|
FAN_DIRECTION = "fan_direction" # Fan direction
|
||||||
|
FAN_SPEED_ENUM = "fan_speed_enum" # Speed mode
|
||||||
|
FAN_SPEED_PERCENT = "fan_speed_percent" # Stepless speed
|
||||||
|
FILTER_RESET = "filter_reset" # Filter (cartridge) reset
|
||||||
|
HUMIDITY_CURRENT = "humidity_current" # Current humidity
|
||||||
|
HUMIDITY_SET = "humidity_set" # Humidity setting
|
||||||
|
LIGHT = "light" # Light
|
||||||
|
LOCK = "lock" # Lock / Child lock
|
||||||
|
MODE = "mode" # Working mode / Mode
|
||||||
|
PUMP_RESET = "pump_reset" # Water pump reset
|
||||||
|
SPEED = "speed" # Speed level
|
||||||
|
START = "start" # Start
|
||||||
|
SWITCH = "switch" # Switch
|
||||||
|
SWITCH_HORIZONTAL = "switch_horizontal" # Horizontal swing flap switch
|
||||||
|
SWITCH_LED = "switch_led" # Switch
|
||||||
|
SWITCH_VERTICAL = "switch_vertical" # Vertical swing flap switch
|
||||||
|
TEMP_CURRENT = "temp_current" # Current temperature in °C
|
||||||
|
TEMP_CURRENT_F = "temp_current_f" # Current temperature in °F
|
||||||
|
TEMP_SET = "temp_set" # Set the temperature in °C
|
||||||
|
TEMP_SET_F = "temp_set_f" # Set the temperature in °F
|
||||||
|
TEMP_UNIT_CONVERT = "temp_unit_convert" # Temperature unit switching
|
||||||
|
TEMP_VALUE = "temp_value" # Color temperature
|
||||||
|
UV = "uv" # UV sterilization
|
||||||
|
WATER_RESET = "water_reset" # Resetting of water usage days
|
||||||
|
WET = "wet" # Humidification
|
||||||
|
WORK_MODE = "work_mode" # Working mode
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Country:
|
class Country:
|
||||||
"""Describe a supported country."""
|
"""Describe a supported country."""
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from tuya_iot import TuyaDevice, TuyaDeviceManager
|
from tuya_iot import TuyaDevice, TuyaDeviceManager
|
||||||
@ -27,23 +26,7 @@ from homeassistant.util.percentage import (
|
|||||||
|
|
||||||
from . import HomeAssistantTuyaData
|
from . import HomeAssistantTuyaData
|
||||||
from .base import TuyaHaEntity
|
from .base import TuyaHaEntity
|
||||||
from .const import DOMAIN, TUYA_DISCOVERY_NEW
|
from .const import DOMAIN, TUYA_DISCOVERY_NEW, DPCode
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
# Fan
|
|
||||||
# https://developer.tuya.com/en/docs/iot/f?id=K9gf45vs7vkge
|
|
||||||
DPCODE_SWITCH = "switch"
|
|
||||||
DPCODE_FAN_SPEED = "fan_speed_percent"
|
|
||||||
DPCODE_MODE = "mode"
|
|
||||||
DPCODE_SWITCH_HORIZONTAL = "switch_horizontal"
|
|
||||||
DPCODE_FAN_DIRECTION = "fan_direction"
|
|
||||||
|
|
||||||
# Air Purifier
|
|
||||||
# https://developer.tuya.com/en/docs/iot/s?id=K9gf48r41mn81
|
|
||||||
DPCODE_AP_FAN_SPEED = "speed"
|
|
||||||
DPCODE_AP_FAN_SPEED_ENUM = "fan_speed_enum"
|
|
||||||
|
|
||||||
TUYA_SUPPORT_TYPE = {
|
TUYA_SUPPORT_TYPE = {
|
||||||
"fs", # Fan
|
"fs", # Fan
|
||||||
@ -82,9 +65,9 @@ class TuyaHaFan(TuyaHaEntity, FanEntity):
|
|||||||
super().__init__(device, device_manager)
|
super().__init__(device, device_manager)
|
||||||
|
|
||||||
self.ha_preset_modes = []
|
self.ha_preset_modes = []
|
||||||
if DPCODE_MODE in self.tuya_device.function:
|
if DPCode.MODE in self.tuya_device.function:
|
||||||
self.ha_preset_modes = json.loads(
|
self.ha_preset_modes = json.loads(
|
||||||
self.tuya_device.function[DPCODE_MODE].values
|
self.tuya_device.function[DPCode.MODE].values
|
||||||
).get("range", [])
|
).get("range", [])
|
||||||
|
|
||||||
# Air purifier fan can be controlled either via the ranged values or via the enum.
|
# Air purifier fan can be controlled either via the ranged values or via the enum.
|
||||||
@ -94,13 +77,13 @@ class TuyaHaFan(TuyaHaEntity, FanEntity):
|
|||||||
self.air_purifier_speed_range_len = 0
|
self.air_purifier_speed_range_len = 0
|
||||||
self.air_purifier_speed_range_enum = []
|
self.air_purifier_speed_range_enum = []
|
||||||
if self.tuya_device.category == "kj" and (
|
if self.tuya_device.category == "kj" and (
|
||||||
DPCODE_AP_FAN_SPEED_ENUM in self.tuya_device.function
|
DPCode.FAN_SPEED_ENUM in self.tuya_device.function
|
||||||
or DPCODE_AP_FAN_SPEED in self.tuya_device.function
|
or DPCode.SPEED in self.tuya_device.function
|
||||||
):
|
):
|
||||||
if DPCODE_AP_FAN_SPEED_ENUM in self.tuya_device.function:
|
if DPCode.FAN_SPEED_ENUM in self.tuya_device.function:
|
||||||
self.dp_code_speed_enum = DPCODE_AP_FAN_SPEED_ENUM
|
self.dp_code_speed_enum = DPCode.FAN_SPEED_ENUM
|
||||||
else:
|
else:
|
||||||
self.dp_code_speed_enum = DPCODE_AP_FAN_SPEED
|
self.dp_code_speed_enum = DPCode.SPEED
|
||||||
|
|
||||||
data = json.loads(
|
data = json.loads(
|
||||||
self.tuya_device.function[self.dp_code_speed_enum].values
|
self.tuya_device.function[self.dp_code_speed_enum].values
|
||||||
@ -111,11 +94,11 @@ class TuyaHaFan(TuyaHaEntity, FanEntity):
|
|||||||
|
|
||||||
def set_preset_mode(self, preset_mode: str) -> None:
|
def set_preset_mode(self, preset_mode: str) -> None:
|
||||||
"""Set the preset mode of the fan."""
|
"""Set the preset mode of the fan."""
|
||||||
self._send_command([{"code": DPCODE_MODE, "value": preset_mode}])
|
self._send_command([{"code": DPCode.MODE, "value": preset_mode}])
|
||||||
|
|
||||||
def set_direction(self, direction: str) -> None:
|
def set_direction(self, direction: str) -> None:
|
||||||
"""Set the direction of the fan."""
|
"""Set the direction of the fan."""
|
||||||
self._send_command([{"code": DPCODE_FAN_DIRECTION, "value": direction}])
|
self._send_command([{"code": DPCode.FAN_DIRECTION, "value": direction}])
|
||||||
|
|
||||||
def set_percentage(self, percentage: int) -> None:
|
def set_percentage(self, percentage: int) -> None:
|
||||||
"""Set the speed of the fan, as a percentage."""
|
"""Set the speed of the fan, as a percentage."""
|
||||||
@ -132,11 +115,13 @@ class TuyaHaFan(TuyaHaEntity, FanEntity):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self._send_command([{"code": DPCODE_FAN_SPEED, "value": percentage}])
|
self._send_command(
|
||||||
|
[{"code": DPCode.FAN_SPEED_PERCENT, "value": percentage}]
|
||||||
|
)
|
||||||
|
|
||||||
def turn_off(self, **kwargs: Any) -> None:
|
def turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Turn the fan off."""
|
"""Turn the fan off."""
|
||||||
self._send_command([{"code": DPCODE_SWITCH, "value": False}])
|
self._send_command([{"code": DPCode.SWITCH, "value": False}])
|
||||||
|
|
||||||
def turn_on(
|
def turn_on(
|
||||||
self,
|
self,
|
||||||
@ -146,28 +131,28 @@ class TuyaHaFan(TuyaHaEntity, FanEntity):
|
|||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Turn on the fan."""
|
"""Turn on the fan."""
|
||||||
self._send_command([{"code": DPCODE_SWITCH, "value": True}])
|
self._send_command([{"code": DPCode.SWITCH, "value": True}])
|
||||||
|
|
||||||
def oscillate(self, oscillating: bool) -> None:
|
def oscillate(self, oscillating: bool) -> None:
|
||||||
"""Oscillate the fan."""
|
"""Oscillate the fan."""
|
||||||
self._send_command([{"code": DPCODE_SWITCH_HORIZONTAL, "value": oscillating}])
|
self._send_command([{"code": DPCode.SWITCH_HORIZONTAL, "value": oscillating}])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
"""Return true if fan is on."""
|
"""Return true if fan is on."""
|
||||||
return self.tuya_device.status.get(DPCODE_SWITCH, False)
|
return self.tuya_device.status.get(DPCode.SWITCH, False)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_direction(self) -> str:
|
def current_direction(self) -> str:
|
||||||
"""Return the current direction of the fan."""
|
"""Return the current direction of the fan."""
|
||||||
if self.tuya_device.status[DPCODE_FAN_DIRECTION]:
|
if self.tuya_device.status[DPCode.FAN_DIRECTION]:
|
||||||
return DIRECTION_FORWARD
|
return DIRECTION_FORWARD
|
||||||
return DIRECTION_REVERSE
|
return DIRECTION_REVERSE
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def oscillating(self) -> bool:
|
def oscillating(self) -> bool:
|
||||||
"""Return true if the fan is oscillating."""
|
"""Return true if the fan is oscillating."""
|
||||||
return self.tuya_device.status.get(DPCODE_SWITCH_HORIZONTAL, False)
|
return self.tuya_device.status.get(DPCode.SWITCH_HORIZONTAL, False)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def preset_modes(self) -> list[str]:
|
def preset_modes(self) -> list[str]:
|
||||||
@ -177,7 +162,7 @@ class TuyaHaFan(TuyaHaEntity, FanEntity):
|
|||||||
@property
|
@property
|
||||||
def preset_mode(self) -> str:
|
def preset_mode(self) -> str:
|
||||||
"""Return the current preset_mode."""
|
"""Return the current preset_mode."""
|
||||||
return self.tuya_device.status[DPCODE_MODE]
|
return self.tuya_device.status[DPCode.MODE]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def percentage(self) -> int | None:
|
def percentage(self) -> int | None:
|
||||||
@ -189,16 +174,16 @@ class TuyaHaFan(TuyaHaEntity, FanEntity):
|
|||||||
self.tuya_device.category == "kj"
|
self.tuya_device.category == "kj"
|
||||||
and self.air_purifier_speed_range_len > 1
|
and self.air_purifier_speed_range_len > 1
|
||||||
and not self.air_purifier_speed_range_enum
|
and not self.air_purifier_speed_range_enum
|
||||||
and DPCODE_AP_FAN_SPEED_ENUM in self.tuya_device.status
|
and DPCode.FAN_SPEED_ENUM in self.tuya_device.status
|
||||||
):
|
):
|
||||||
# if air-purifier speed enumeration is supported we will prefer it.
|
# if air-purifier speed enumeration is supported we will prefer it.
|
||||||
return ordered_list_item_to_percentage(
|
return ordered_list_item_to_percentage(
|
||||||
self.air_purifier_speed_range_enum,
|
self.air_purifier_speed_range_enum,
|
||||||
self.tuya_device.status[DPCODE_AP_FAN_SPEED_ENUM],
|
self.tuya_device.status[DPCode.FAN_SPEED_ENUM],
|
||||||
)
|
)
|
||||||
|
|
||||||
# some type may not have the fan_speed_percent key
|
# some type may not have the fan_speed_percent key
|
||||||
return self.tuya_device.status.get(DPCODE_FAN_SPEED)
|
return self.tuya_device.status.get(DPCode.FAN_SPEED_PERCENT)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def speed_count(self) -> int:
|
def speed_count(self) -> int:
|
||||||
@ -211,19 +196,19 @@ class TuyaHaFan(TuyaHaEntity, FanEntity):
|
|||||||
def supported_features(self):
|
def supported_features(self):
|
||||||
"""Flag supported features."""
|
"""Flag supported features."""
|
||||||
supports = 0
|
supports = 0
|
||||||
if DPCODE_MODE in self.tuya_device.status:
|
if DPCode.MODE in self.tuya_device.status:
|
||||||
supports |= SUPPORT_PRESET_MODE
|
supports |= SUPPORT_PRESET_MODE
|
||||||
if DPCODE_FAN_SPEED in self.tuya_device.status:
|
if DPCode.FAN_SPEED_PERCENT in self.tuya_device.status:
|
||||||
supports |= SUPPORT_SET_SPEED
|
supports |= SUPPORT_SET_SPEED
|
||||||
if DPCODE_SWITCH_HORIZONTAL in self.tuya_device.status:
|
if DPCode.SWITCH_HORIZONTAL in self.tuya_device.status:
|
||||||
supports |= SUPPORT_OSCILLATE
|
supports |= SUPPORT_OSCILLATE
|
||||||
if DPCODE_FAN_DIRECTION in self.tuya_device.status:
|
if DPCode.FAN_DIRECTION in self.tuya_device.status:
|
||||||
supports |= SUPPORT_DIRECTION
|
supports |= SUPPORT_DIRECTION
|
||||||
|
|
||||||
# Air Purifier specific
|
# Air Purifier specific
|
||||||
if (
|
if (
|
||||||
DPCODE_AP_FAN_SPEED in self.tuya_device.status
|
DPCode.SPEED in self.tuya_device.status
|
||||||
or DPCODE_AP_FAN_SPEED_ENUM in self.tuya_device.status
|
or DPCode.FAN_SPEED_ENUM in self.tuya_device.status
|
||||||
):
|
):
|
||||||
supports |= SUPPORT_SET_SPEED
|
supports |= SUPPORT_SET_SPEED
|
||||||
return supports
|
return supports
|
||||||
|
@ -24,21 +24,10 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
|
|
||||||
from . import HomeAssistantTuyaData
|
from . import HomeAssistantTuyaData
|
||||||
from .base import TuyaHaEntity
|
from .base import TuyaHaEntity
|
||||||
from .const import DOMAIN, TUYA_DISCOVERY_NEW
|
from .const import DOMAIN, TUYA_DISCOVERY_NEW, DPCode
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# Light(dj)
|
|
||||||
# https://developer.tuya.com/en/docs/iot/f?id=K9i5ql3v98hn3
|
|
||||||
DPCODE_SWITCH = "switch_led"
|
|
||||||
DPCODE_WORK_MODE = "work_mode"
|
|
||||||
DPCODE_BRIGHT_VALUE = "bright_value"
|
|
||||||
DPCODE_TEMP_VALUE = "temp_value"
|
|
||||||
DPCODE_COLOUR_DATA = "colour_data"
|
|
||||||
DPCODE_COLOUR_DATA_V2 = "colour_data_v2"
|
|
||||||
DPCODE_LIGHT = "light"
|
|
||||||
|
|
||||||
MIREDS_MAX = 500
|
MIREDS_MAX = 500
|
||||||
MIREDS_MIN = 153
|
MIREDS_MIN = 153
|
||||||
|
|
||||||
@ -50,6 +39,7 @@ HSV_HA_SATURATION_MAX = 100
|
|||||||
WORK_MODE_WHITE = "white"
|
WORK_MODE_WHITE = "white"
|
||||||
WORK_MODE_COLOUR = "colour"
|
WORK_MODE_COLOUR = "colour"
|
||||||
|
|
||||||
|
# https://developer.tuya.com/en/docs/iot/standarddescription?id=K9i5ql6waswzq
|
||||||
TUYA_SUPPORT_TYPE = {
|
TUYA_SUPPORT_TYPE = {
|
||||||
"dj", # Light
|
"dj", # Light
|
||||||
"dd", # Light strip
|
"dd", # Light strip
|
||||||
@ -102,16 +92,16 @@ class TuyaHaLight(TuyaHaEntity, LightEntity):
|
|||||||
|
|
||||||
def __init__(self, device: TuyaDevice, device_manager: TuyaDeviceManager) -> None:
|
def __init__(self, device: TuyaDevice, device_manager: TuyaDeviceManager) -> None:
|
||||||
"""Init TuyaHaLight."""
|
"""Init TuyaHaLight."""
|
||||||
self.dp_code_bright = DPCODE_BRIGHT_VALUE
|
self.dp_code_bright = DPCode.BRIGHT_VALUE
|
||||||
self.dp_code_temp = DPCODE_TEMP_VALUE
|
self.dp_code_temp = DPCode.TEMP_VALUE
|
||||||
self.dp_code_colour = DPCODE_COLOUR_DATA
|
self.dp_code_colour = DPCode.COLOUR_DATA
|
||||||
|
|
||||||
for key in device.function:
|
for key in device.function:
|
||||||
if key.startswith(DPCODE_BRIGHT_VALUE):
|
if key.startswith(DPCode.BRIGHT_VALUE):
|
||||||
self.dp_code_bright = key
|
self.dp_code_bright = key
|
||||||
elif key.startswith(DPCODE_TEMP_VALUE):
|
elif key.startswith(DPCode.TEMP_VALUE):
|
||||||
self.dp_code_temp = key
|
self.dp_code_temp = key
|
||||||
elif key.startswith(DPCODE_COLOUR_DATA):
|
elif key.startswith(DPCode.COLOUR_DATA):
|
||||||
self.dp_code_colour = key
|
self.dp_code_colour = key
|
||||||
|
|
||||||
super().__init__(device, device_manager)
|
super().__init__(device, device_manager)
|
||||||
@ -119,7 +109,7 @@ class TuyaHaLight(TuyaHaEntity, LightEntity):
|
|||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
"""Return true if light is on."""
|
"""Return true if light is on."""
|
||||||
return self.tuya_device.status.get(DPCODE_SWITCH, False)
|
return self.tuya_device.status.get(DPCode.SWITCH_LED, False)
|
||||||
|
|
||||||
def turn_on(self, **kwargs: Any) -> None:
|
def turn_on(self, **kwargs: Any) -> None:
|
||||||
"""Turn on or control the light."""
|
"""Turn on or control the light."""
|
||||||
@ -127,12 +117,12 @@ class TuyaHaLight(TuyaHaEntity, LightEntity):
|
|||||||
_LOGGER.debug("light kwargs-> %s", kwargs)
|
_LOGGER.debug("light kwargs-> %s", kwargs)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
DPCODE_LIGHT in self.tuya_device.status
|
DPCode.LIGHT in self.tuya_device.status
|
||||||
and DPCODE_SWITCH not in self.tuya_device.status
|
and DPCode.SWITCH_LED not in self.tuya_device.status
|
||||||
):
|
):
|
||||||
commands += [{"code": DPCODE_LIGHT, "value": True}]
|
commands += [{"code": DPCode.LIGHT, "value": True}]
|
||||||
else:
|
else:
|
||||||
commands += [{"code": DPCODE_SWITCH, "value": True}]
|
commands += [{"code": DPCode.SWITCH_LED, "value": True}]
|
||||||
|
|
||||||
if ATTR_BRIGHTNESS in kwargs:
|
if ATTR_BRIGHTNESS in kwargs:
|
||||||
if self._work_mode().startswith(WORK_MODE_COLOUR):
|
if self._work_mode().startswith(WORK_MODE_COLOUR):
|
||||||
@ -177,8 +167,8 @@ class TuyaHaLight(TuyaHaEntity, LightEntity):
|
|||||||
commands += [
|
commands += [
|
||||||
{"code": self.dp_code_colour, "value": json.dumps(colour_data)}
|
{"code": self.dp_code_colour, "value": json.dumps(colour_data)}
|
||||||
]
|
]
|
||||||
if self.tuya_device.status[DPCODE_WORK_MODE] != "colour":
|
if self.tuya_device.status[DPCode.WORK_MODE] != "colour":
|
||||||
commands += [{"code": DPCODE_WORK_MODE, "value": "colour"}]
|
commands += [{"code": DPCode.WORK_MODE, "value": "colour"}]
|
||||||
|
|
||||||
if ATTR_COLOR_TEMP in kwargs:
|
if ATTR_COLOR_TEMP in kwargs:
|
||||||
# temp color
|
# temp color
|
||||||
@ -200,20 +190,20 @@ class TuyaHaLight(TuyaHaEntity, LightEntity):
|
|||||||
)
|
)
|
||||||
commands += [{"code": self.dp_code_bright, "value": int(tuya_brightness)}]
|
commands += [{"code": self.dp_code_bright, "value": int(tuya_brightness)}]
|
||||||
|
|
||||||
if self.tuya_device.status[DPCODE_WORK_MODE] != "white":
|
if self.tuya_device.status[DPCode.WORK_MODE] != "white":
|
||||||
commands += [{"code": DPCODE_WORK_MODE, "value": "white"}]
|
commands += [{"code": DPCode.WORK_MODE, "value": "white"}]
|
||||||
|
|
||||||
self._send_command(commands)
|
self._send_command(commands)
|
||||||
|
|
||||||
def turn_off(self, **kwargs: Any) -> None:
|
def turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Instruct the light to turn off."""
|
"""Instruct the light to turn off."""
|
||||||
if (
|
if (
|
||||||
DPCODE_LIGHT in self.tuya_device.status
|
DPCode.LIGHT in self.tuya_device.status
|
||||||
and DPCODE_SWITCH not in self.tuya_device.status
|
and DPCode.SWITCH_LED not in self.tuya_device.status
|
||||||
):
|
):
|
||||||
commands = [{"code": DPCODE_LIGHT, "value": False}]
|
commands = [{"code": DPCode.LIGHT, "value": False}]
|
||||||
else:
|
else:
|
||||||
commands = [{"code": DPCODE_SWITCH, "value": False}]
|
commands = [{"code": DPCode.SWITCH_LED, "value": False}]
|
||||||
self._send_command(commands)
|
self._send_command(commands)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -319,7 +309,7 @@ class TuyaHaLight(TuyaHaEntity, LightEntity):
|
|||||||
return None
|
return None
|
||||||
colour_data = json.loads(colour_json)
|
colour_data = json.loads(colour_json)
|
||||||
if (
|
if (
|
||||||
self.dp_code_colour == DPCODE_COLOUR_DATA_V2
|
self.dp_code_colour == DPCode.COLOUR_DATA_V2
|
||||||
or colour_data.get("v", 0) > 255
|
or colour_data.get("v", 0) > 255
|
||||||
or colour_data.get("s", 0) > 255
|
or colour_data.get("s", 0) > 255
|
||||||
):
|
):
|
||||||
@ -327,7 +317,7 @@ class TuyaHaLight(TuyaHaEntity, LightEntity):
|
|||||||
return DEFAULT_HSV
|
return DEFAULT_HSV
|
||||||
|
|
||||||
def _work_mode(self) -> str:
|
def _work_mode(self) -> str:
|
||||||
return self.tuya_device.status.get(DPCODE_WORK_MODE, "")
|
return self.tuya_device.status.get(DPCode.WORK_MODE, "")
|
||||||
|
|
||||||
def _get_hsv(self) -> dict[str, int]:
|
def _get_hsv(self) -> dict[str, int]:
|
||||||
return json.loads(self.tuya_device.status[self.dp_code_colour])
|
return json.loads(self.tuya_device.status[self.dp_code_colour])
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
"""Support for Tuya switches."""
|
"""Support for Tuya switches."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from tuya_iot import TuyaDevice, TuyaDeviceManager
|
from tuya_iot import TuyaDevice, TuyaDeviceManager
|
||||||
@ -14,10 +13,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
|
|
||||||
from . import HomeAssistantTuyaData
|
from . import HomeAssistantTuyaData
|
||||||
from .base import TuyaHaEntity
|
from .base import TuyaHaEntity
|
||||||
from .const import DOMAIN, TUYA_DISCOVERY_NEW
|
from .const import DOMAIN, TUYA_DISCOVERY_NEW, DPCode
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
# https://developer.tuya.com/en/docs/iot/standarddescription?id=K9i5ql6waswzq
|
||||||
TUYA_SUPPORT_TYPE = {
|
TUYA_SUPPORT_TYPE = {
|
||||||
"kg", # Switch
|
"kg", # Switch
|
||||||
"cz", # Socket
|
"cz", # Socket
|
||||||
@ -29,28 +27,6 @@ TUYA_SUPPORT_TYPE = {
|
|||||||
"xxj", # Diffuser
|
"xxj", # Diffuser
|
||||||
}
|
}
|
||||||
|
|
||||||
# Switch(kg), Socket(cz), Power Strip(pc)
|
|
||||||
# https://developer.tuya.com/en/docs/iot/categorykgczpc?id=Kaiuz08zj1l4y
|
|
||||||
DPCODE_SWITCH = "switch"
|
|
||||||
|
|
||||||
# Air Purifier
|
|
||||||
# https://developer.tuya.com/en/docs/iot/categorykj?id=Kaiuz1atqo5l7
|
|
||||||
# Pet Water Feeder
|
|
||||||
# https://developer.tuya.com/en/docs/iot/f?id=K9gf46aewxem5
|
|
||||||
DPCODE_ANION = "anion" # Air Purifier - Ionizer unit
|
|
||||||
# Air Purifier - Filter cartridge resetting; Pet Water Feeder - Filter cartridge resetting
|
|
||||||
DPCODE_FRESET = "filter_reset"
|
|
||||||
DPCODE_LIGHT = "light" # Air Purifier - Light
|
|
||||||
DPCODE_LOCK = "lock" # Air Purifier - Child lock
|
|
||||||
# Air Purifier - UV sterilization; Pet Water Feeder - UV sterilization
|
|
||||||
DPCODE_UV = "uv"
|
|
||||||
DPCODE_WET = "wet" # Air Purifier - Humidification unit
|
|
||||||
DPCODE_PRESET = "pump_reset" # Pet Water Feeder - Water pump resetting
|
|
||||||
DPCODE_WRESET = "water_reset" # Pet Water Feeder - Resetting of water usage days
|
|
||||||
|
|
||||||
|
|
||||||
DPCODE_START = "start"
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||||
@ -88,12 +64,12 @@ def _setup_entities(
|
|||||||
for function in device.function:
|
for function in device.function:
|
||||||
if device.category == "kj":
|
if device.category == "kj":
|
||||||
if function in [
|
if function in [
|
||||||
DPCODE_ANION,
|
DPCode.ANION,
|
||||||
DPCODE_FRESET,
|
DPCode.FILTER_RESET,
|
||||||
DPCODE_LIGHT,
|
DPCode.LIGHT,
|
||||||
DPCODE_LOCK,
|
DPCode.LOCK,
|
||||||
DPCODE_UV,
|
DPCode.UV,
|
||||||
DPCODE_WET,
|
DPCode.WET,
|
||||||
]:
|
]:
|
||||||
entities.append(TuyaHaSwitch(device, device_manager, function))
|
entities.append(TuyaHaSwitch(device, device_manager, function))
|
||||||
|
|
||||||
@ -101,17 +77,17 @@ def _setup_entities(
|
|||||||
if (
|
if (
|
||||||
function
|
function
|
||||||
in [
|
in [
|
||||||
DPCODE_FRESET,
|
DPCode.FILTER_RESET,
|
||||||
DPCODE_UV,
|
DPCode.UV,
|
||||||
DPCODE_PRESET,
|
DPCode.PUMP_RESET,
|
||||||
DPCODE_WRESET,
|
DPCode.WATER_RESET,
|
||||||
]
|
]
|
||||||
or function.startswith(DPCODE_SWITCH)
|
or function.startswith(DPCode.SWITCH)
|
||||||
):
|
):
|
||||||
entities.append(TuyaHaSwitch(device, device_manager, function))
|
entities.append(TuyaHaSwitch(device, device_manager, function))
|
||||||
|
|
||||||
elif function.startswith(DPCODE_START) or function.startswith(
|
elif function.startswith(DPCode.START) or function.startswith(
|
||||||
DPCODE_SWITCH
|
DPCode.SWITCH
|
||||||
):
|
):
|
||||||
entities.append(TuyaHaSwitch(device, device_manager, function))
|
entities.append(TuyaHaSwitch(device, device_manager, function))
|
||||||
|
|
||||||
@ -121,8 +97,8 @@ def _setup_entities(
|
|||||||
class TuyaHaSwitch(TuyaHaEntity, SwitchEntity):
|
class TuyaHaSwitch(TuyaHaEntity, SwitchEntity):
|
||||||
"""Tuya Switch Device."""
|
"""Tuya Switch Device."""
|
||||||
|
|
||||||
dp_code_switch = DPCODE_SWITCH
|
dp_code_switch = DPCode.SWITCH
|
||||||
dp_code_start = DPCODE_START
|
dp_code_start = DPCode.START
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, device: TuyaDevice, device_manager: TuyaDeviceManager, dp_code: str = ""
|
self, device: TuyaDevice, device_manager: TuyaDeviceManager, dp_code: str = ""
|
||||||
@ -132,15 +108,11 @@ class TuyaHaSwitch(TuyaHaEntity, SwitchEntity):
|
|||||||
|
|
||||||
self.dp_code = dp_code
|
self.dp_code = dp_code
|
||||||
self.channel = (
|
self.channel = (
|
||||||
dp_code.replace(DPCODE_SWITCH, "")
|
dp_code.replace(DPCode.SWITCH, "")
|
||||||
if dp_code.startswith(DPCODE_SWITCH)
|
if dp_code.startswith(DPCode.SWITCH)
|
||||||
else dp_code
|
else dp_code
|
||||||
)
|
)
|
||||||
|
self._attr_unique_id = f"{super().unique_id}{self.channel}"
|
||||||
@property
|
|
||||||
def unique_id(self) -> str | None:
|
|
||||||
"""Return a unique ID."""
|
|
||||||
return f"{super().unique_id}{self.channel}"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str | None:
|
def name(self) -> str | None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user