Skip to content

Commit

Permalink
Improve Tuya local temp calibration, remove setpoint min/max (#3877)
Browse files Browse the repository at this point in the history
  • Loading branch information
prairiesnpr authored Feb 16, 2025
1 parent 2a96ada commit 947a8ae
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 17 deletions.
49 changes: 43 additions & 6 deletions tests/test_tuya_thermostat.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@
Thermostat.AttributeDefs.occupied_heating_setpoint,
2500,
), # Setpoint to 25, dp 16
(
"_TZE204_p3lqqy2r",
b"\t\x17\x02\x00\n\x1c\x02\x00\x04\x00\x00\x00\x00",
Thermostat.AttributeDefs.local_temperature_calibration,
0,
), # Local calibration to 0, dp 28
(
"_TZE204_p3lqqy2r",
b"\t\x1c\x02\x00\x0fh\x01\x00\x01\x01",
Expand Down Expand Up @@ -121,3 +115,46 @@ async def test_tuya_no_mcu_version(zigpy_device_from_v2_quirk):

tuya_cluster.handle_message(hdr, args)
assert len(cluster_listener.attribute_updates) == 0


@pytest.mark.parametrize(
"manuf,msg,dp_id,value",
[
(
"_TZE204_p3lqqy2r",
b"\t\x1d\x02\x00\x10\x1c\x02\x00\x04\xff\xff\xff\xf7",
28,
-9,
), # Local temp calibration to -2, dp 28
(
"_TZE204_lzriup1j",
b"\t\x1d\x02\x00\x10\x13\x02\x00\x04\xff\xff\xff\x9d",
19,
-99,
), # Local temp calibration to -9.9, dp 19
],
)
async def test_handle_get_data_tmcu(
zigpy_device_from_v2_quirk, manuf, msg, dp_id, value
):
"""Test handle_get_data for multiple attributes."""

attr_id = (0xEF << 8) | dp_id

quirked = zigpy_device_from_v2_quirk(manuf, "TS0601")
ep = quirked.endpoints[1]

assert ep.tuya_manufacturer is not None
assert isinstance(ep.tuya_manufacturer, TuyaMCUCluster)

tmcu_listener = ClusterListener(ep.tuya_manufacturer)

hdr, data = ep.tuya_manufacturer.deserialize(msg)
status = ep.tuya_manufacturer.handle_get_data(data.data)
assert status == foundation.Status.SUCCESS

assert len(tmcu_listener.attribute_updates) == 1
assert tmcu_listener.attribute_updates[0][0] == attr_id
assert tmcu_listener.attribute_updates[0][1] == value

assert ep.tuya_manufacturer.get(attr_id) == value
49 changes: 49 additions & 0 deletions tests/test_tuya_trv.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,52 @@ async def async_success(*args, **kwargs):
assert status == [
foundation.WriteAttributesStatusRecord(foundation.Status.SUCCESS)
]


@pytest.mark.parametrize(
"manuf,msg,dp_id,value",
[
(
"_TZE200_3yp57tby",
b"\t\x1d\x02\x00\x10\x1b\x02\x00\x04\xff\xff\xff\xfa",
27,
-6,
), # Local temp calibration to -6, dp 27
(
"_TZE204_rtrmfadk",
b"\t\x1d\x02\x00\x10\x65\x02\x00\x04\xff\xff\xff\xfa",
101,
-6,
), # Local temp calibration to -6, dp 101
(
"_TZE284_ogx8u5z6",
b"\t\x1d\x02\x00\x10\x2f\x02\x00\x04\xff\xff\xff\xfa",
47,
-6,
), # Local temp calibration to -6, dp 47
],
)
async def test_handle_get_data_tmcu(
zigpy_device_from_v2_quirk, manuf, msg, dp_id, value
):
"""Test handle_get_data for multiple attributes."""

attr_id = (0xEF << 8) | dp_id

quirked = zigpy_device_from_v2_quirk(manuf, "TS0601")
ep = quirked.endpoints[1]

assert ep.tuya_manufacturer is not None
assert isinstance(ep.tuya_manufacturer, TuyaMCUCluster)

tmcu_listener = ClusterListener(ep.tuya_manufacturer)

hdr, data = ep.tuya_manufacturer.deserialize(msg)
status = ep.tuya_manufacturer.handle_get_data(data.data)
assert status == foundation.Status.SUCCESS

assert len(tmcu_listener.attribute_updates) == 1
assert tmcu_listener.attribute_updates[0][0] == attr_id
assert tmcu_listener.attribute_updates[0][1] == value

assert ep.tuya_manufacturer.get(attr_id) == value
32 changes: 23 additions & 9 deletions zhaquirks/tuya/tuya_thermostat.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ def __init__(self, *args, **kwargs):
)
self.add_unsupported_attribute(Thermostat.AttributeDefs.pi_heating_demand.id)

# Previously mapped, marking as explicitly unsupported.
self.add_unsupported_attribute(
Thermostat.AttributeDefs.local_temperature_calibration.id
)


class NoManufTimeNoVersionRespTuyaMCUCluster(TuyaMCUCluster):
"""Tuya Manufacturer Cluster with set_time mod."""
Expand Down Expand Up @@ -173,12 +178,16 @@ def handle_mcu_version_response(
attribute_name=TuyaThermostat.AttributeDefs.local_temperature.name,
converter=lambda x: x * 100,
)
.tuya_dp(
.tuya_number(
dp_id=28,
ep_attribute=TuyaThermostat.ep_attribute,
attribute_name=Thermostat.AttributeDefs.local_temperature_calibration.name,
converter=lambda x: x * 100,
dp_converter=lambda x: x // 100,
attribute_name=TuyaThermostat.AttributeDefs.local_temperature_calibration.name,
type=t.int32s,
min_value=-9,
max_value=9,
unit=UnitOfTemperature.CELSIUS,
step=1,
translation_key="local_temperature_calibration",
fallback_name="Local temperature calibration",
)
.tuya_switch(
dp_id=30,
Expand Down Expand Up @@ -341,12 +350,17 @@ def handle_mcu_version_response(
converter=lambda x: x * 10,
dp_converter=lambda x: x // 10,
)
.tuya_dp(
.tuya_number(
dp_id=19,
ep_attribute=TuyaThermostat.ep_attribute,
attribute_name=TuyaThermostat.AttributeDefs.local_temperature_calibration.name,
converter=lambda x: x * 10,
dp_converter=lambda x: x // 10,
type=t.int32s,
min_value=-9.9,
max_value=9.9,
unit=UnitOfTemperature.CELSIUS,
step=0.1,
multiplier=0.1,
translation_key="local_temperature_calibration",
fallback_name="Local temperature calibration",
)
.tuya_dp(
dp_id=101,
Expand Down
15 changes: 13 additions & 2 deletions zhaquirks/tuya/tuya_trv.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ class TuyaThermostatV2(Thermostat, TuyaAttributesCluster):
"""Tuya local thermostat cluster."""

_CONSTANT_ATTRIBUTES = {
Thermostat.AttributeDefs.min_heat_setpoint_limit.id: 500,
Thermostat.AttributeDefs.max_heat_setpoint_limit.id: 3000,
Thermostat.AttributeDefs.abs_min_heat_setpoint_limit.id: 500,
Thermostat.AttributeDefs.abs_max_heat_setpoint_limit.id: 3000,
Thermostat.AttributeDefs.ctrl_sequence_of_oper.id: Thermostat.ControlSequenceOfOperation.Heating_Only,
}

Expand All @@ -67,6 +67,17 @@ def __init__(self, *args, **kwargs):
)
self.add_unsupported_attribute(Thermostat.AttributeDefs.pi_heating_demand.id)

# Previously mapped, marking as explicitly unsupported.
self.add_unsupported_attribute(
Thermostat.AttributeDefs.local_temperature_calibration.id
)
self.add_unsupported_attribute(
Thermostat.AttributeDefs.min_heat_setpoint_limit.id
)
self.add_unsupported_attribute(
Thermostat.AttributeDefs.max_heat_setpoint_limit.id
)


(
TuyaQuirkBuilder("_TYST11_KGbxAXL2", "GbxAXL2")
Expand Down

0 comments on commit 947a8ae

Please sign in to comment.