From 3a919a849a4fb17822e39e138cde59e1f1db974b Mon Sep 17 00:00:00 2001 From: marcopetrini Date: Fri, 29 Aug 2025 00:39:19 +0200 Subject: [PATCH 1/2] Add quirk for Tuya TS0601 thermostat (_TZE200_mzik0ov2) --- tests/test_tuya_thermostat.py | 35 +++++++++++++ zhaquirks/tuya/tuya_thermostat.py | 81 +++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/tests/test_tuya_thermostat.py b/tests/test_tuya_thermostat.py index 5bac81bf61..2f21752aa9 100644 --- a/tests/test_tuya_thermostat.py +++ b/tests/test_tuya_thermostat.py @@ -78,6 +78,34 @@ Thermostat.AttributeDefs.system_mode, Thermostat.SystemMode.Heat, ), # Set to heat, dp 1 + + ( + "_TZE200_mzik0ov2", + b"\t\x13\x02\x00\x06\x7D\x01\x00\x01\x01", + Thermostat.AttributeDefs.system_mode, + Thermostat.SystemMode.Heat, + ), # Set to heat, dp 125 + + ( + "_TZE200_mzik0ov2", + b"\t\x16\x02\x00\t\x10\x02\x00\x04\x00\x00\x00\xEB", + Thermostat.AttributeDefs.local_temperature, + 2350, + ), # Current temp 23.5, dp 16 + + ( + "_TZE200_mzik0ov2", + b"\t\x15\x02\x00\x08\x32\x02\x00\x04\x00\x00\x00\xAA", + Thermostat.AttributeDefs.occupied_heating_setpoint, + 1700, + ), # Setpoint to 17, dp 50 + + ( + "_TZE200_mzik0ov2", + b"\t\x1d\x02\x00\x10\x72\x02\x00\x04\x00\x00\x00\x23", + Thermostat.AttributeDefs.max_heat_setpoint_limit, + 3500, + ) # Max heat set point, dp 114 ], ) async def test_handle_get_data(zigpy_device_from_v2_quirk, manuf, msg, attr, value): @@ -144,6 +172,13 @@ async def test_tuya_no_mcu_version(zigpy_device_from_v2_quirk): 19, -99, ), # Local temp calibration to -9.9, dp 19 + + ( + "_TZE200_mzik0ov2", + b"\t\x1d\x02\x00\x10\x6D\x02\x00\x04\xff\xff\xff\xec", + 109, + -20, + ), # Local temp calibration to -2, dp 109 ], ) async def test_handle_get_data_tmcu( diff --git a/zhaquirks/tuya/tuya_thermostat.py b/zhaquirks/tuya/tuya_thermostat.py index 5e97145602..048a0b4c2d 100644 --- a/zhaquirks/tuya/tuya_thermostat.py +++ b/zhaquirks/tuya/tuya_thermostat.py @@ -66,6 +66,12 @@ class PresetModeV04(t.enum8): Auto = 0x01 Eco = 0x03 +class PresetModeV05(t.enum8): + """Tuya preset mode v05 enum.""" + + Manual = 0x00 + Auto = 0x01 + Temporary_Manual = 0x03 class SensorMode(t.enum8): """Tuya sensor mode enum.""" @@ -603,3 +609,78 @@ def handle_mcu_version_response( .skip_configuration() .add_to_registry() ) +# ANFEL HY09BW ZIGBEE +( + TuyaQuirkBuilder("_TZE200_mzik0ov2", "TS0601") + .tuya_dp( + dp_id=125, + ep_attribute=TuyaThermostat.ep_attribute, + attribute_name=TuyaThermostat.AttributeDefs.system_mode.name, + converter=lambda x: { + True: Thermostat.SystemMode.Heat, + False: Thermostat.SystemMode.Off, + }[x], + dp_converter=lambda x: { + Thermostat.SystemMode.Heat: True, + Thermostat.SystemMode.Off: False, + }[x], + ) + .tuya_dp( + dp_id=50, + ep_attribute=TuyaThermostat.ep_attribute, + attribute_name=TuyaThermostat.AttributeDefs.occupied_heating_setpoint.name, + converter=lambda x: x * 10, + dp_converter=lambda x: x // 10, + ) + .tuya_dp( + dp_id=16, + ep_attribute=TuyaThermostat.ep_attribute, + attribute_name=TuyaThermostat.AttributeDefs.local_temperature.name, + converter=lambda x: x * 10, + ) + + .tuya_enum( + dp_id=128, + attribute_name="preset_mode", + enum_class=PresetModeV05, + translation_key="preset_mode", + fallback_name="Preset mode" + ) + + .tuya_number( + dp_id=109, + attribute_name=TuyaThermostat.AttributeDefs.local_temperature_calibration.name, + type=t.int32s, + min_value=-9, + max_value=9, + unit=UnitOfTemperature.CELSIUS, + step=1, + multiplier=0.1, + translation_key="local_temperature_calibration", + fallback_name="Local temperature calibration", + ) + + .tuya_number( + dp_id=110, + attribute_name="regulator_set_point", + type=t.uint16_t, + unit=UnitOfTemperature.CELSIUS, + min_value=0.5, + max_value=2.5, + step=0.5, + multiplier=0.1, + translation_key="regulator_set_point", + fallback_name="Regulator set point", + ) + + .tuya_dp( + dp_id=114, + ep_attribute=TuyaThermostat.ep_attribute, + attribute_name=TuyaThermostat.AttributeDefs.max_heat_setpoint_limit.name, + converter=lambda x: x * 100, + dp_converter=lambda x: x // 100, + ) + .adds(TuyaThermostat) + .skip_configuration() + .add_to_registry() +) From cdf56ddcc86767dced0657d86c61b3e7b236f485 Mon Sep 17 00:00:00 2001 From: marcopetrini Date: Fri, 29 Aug 2025 00:53:15 +0200 Subject: [PATCH 2/2] Add quirk for Tuya TS0601 thermostat (_TZE200_mzik0ov2) --- tests/test_tuya_thermostat.py | 19 +++++++------------ zhaquirks/tuya/tuya_thermostat.py | 8 +++----- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/tests/test_tuya_thermostat.py b/tests/test_tuya_thermostat.py index 2f21752aa9..534b6cf169 100644 --- a/tests/test_tuya_thermostat.py +++ b/tests/test_tuya_thermostat.py @@ -78,34 +78,30 @@ Thermostat.AttributeDefs.system_mode, Thermostat.SystemMode.Heat, ), # Set to heat, dp 1 - ( "_TZE200_mzik0ov2", - b"\t\x13\x02\x00\x06\x7D\x01\x00\x01\x01", + b"\t\x13\x02\x00\x06\x7d\x01\x00\x01\x01", Thermostat.AttributeDefs.system_mode, Thermostat.SystemMode.Heat, ), # Set to heat, dp 125 - ( "_TZE200_mzik0ov2", - b"\t\x16\x02\x00\t\x10\x02\x00\x04\x00\x00\x00\xEB", + b"\t\x16\x02\x00\t\x10\x02\x00\x04\x00\x00\x00\xeb", Thermostat.AttributeDefs.local_temperature, 2350, - ), # Current temp 23.5, dp 16 - + ), # Current temp 23.5, dp 16 ( "_TZE200_mzik0ov2", - b"\t\x15\x02\x00\x08\x32\x02\x00\x04\x00\x00\x00\xAA", + b"\t\x15\x02\x00\x08\x32\x02\x00\x04\x00\x00\x00\xaa", Thermostat.AttributeDefs.occupied_heating_setpoint, 1700, ), # Setpoint to 17, dp 50 - ( "_TZE200_mzik0ov2", b"\t\x1d\x02\x00\x10\x72\x02\x00\x04\x00\x00\x00\x23", Thermostat.AttributeDefs.max_heat_setpoint_limit, 3500, - ) # Max heat set point, dp 114 + ), # Max heat set point, dp 114 ], ) async def test_handle_get_data(zigpy_device_from_v2_quirk, manuf, msg, attr, value): @@ -172,13 +168,12 @@ async def test_tuya_no_mcu_version(zigpy_device_from_v2_quirk): 19, -99, ), # Local temp calibration to -9.9, dp 19 - ( "_TZE200_mzik0ov2", - b"\t\x1d\x02\x00\x10\x6D\x02\x00\x04\xff\xff\xff\xec", + b"\t\x1d\x02\x00\x10\x6d\x02\x00\x04\xff\xff\xff\xec", 109, -20, - ), # Local temp calibration to -2, dp 109 + ), # Local temp calibration to -2, dp 109 ], ) async def test_handle_get_data_tmcu( diff --git a/zhaquirks/tuya/tuya_thermostat.py b/zhaquirks/tuya/tuya_thermostat.py index 048a0b4c2d..c4755f5c4a 100644 --- a/zhaquirks/tuya/tuya_thermostat.py +++ b/zhaquirks/tuya/tuya_thermostat.py @@ -66,6 +66,7 @@ class PresetModeV04(t.enum8): Auto = 0x01 Eco = 0x03 + class PresetModeV05(t.enum8): """Tuya preset mode v05 enum.""" @@ -73,6 +74,7 @@ class PresetModeV05(t.enum8): Auto = 0x01 Temporary_Manual = 0x03 + class SensorMode(t.enum8): """Tuya sensor mode enum.""" @@ -638,15 +640,13 @@ def handle_mcu_version_response( attribute_name=TuyaThermostat.AttributeDefs.local_temperature.name, converter=lambda x: x * 10, ) - .tuya_enum( dp_id=128, attribute_name="preset_mode", enum_class=PresetModeV05, translation_key="preset_mode", - fallback_name="Preset mode" + fallback_name="Preset mode", ) - .tuya_number( dp_id=109, attribute_name=TuyaThermostat.AttributeDefs.local_temperature_calibration.name, @@ -659,7 +659,6 @@ def handle_mcu_version_response( translation_key="local_temperature_calibration", fallback_name="Local temperature calibration", ) - .tuya_number( dp_id=110, attribute_name="regulator_set_point", @@ -672,7 +671,6 @@ def handle_mcu_version_response( translation_key="regulator_set_point", fallback_name="Regulator set point", ) - .tuya_dp( dp_id=114, ep_attribute=TuyaThermostat.ep_attribute,