Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small improvements to the tuya ts0021 quirk #3373

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 43 additions & 9 deletions tests/test_tuya.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,65 +152,99 @@ async def test_singleswitch_state_report(zigpy_device_from_quirk, quirk):


@pytest.mark.parametrize(
"quirk,raw_event,expected_attr_name,expected_attr_value",
"quirk,raw_event,button_number,press_type,expected_attr_value",
(
(
zhaquirks.tuya.ts0021.TS0021,
ZCL_TUYA_BUTTON_1_SINGLE_PRESS,
"btn_1_pressed",
1,
"single",
0x00,
),
(
zhaquirks.tuya.ts0021.TS0021,
ZCL_TUYA_BUTTON_1_DOUBLE_PRESS,
"btn_1_pressed",
1,
"double",
0x01,
),
(
zhaquirks.tuya.ts0021.TS0021,
ZCL_TUYA_BUTTON_1_LONG_PRESS,
"btn_1_pressed",
1,
"long",
0x02,
),
(
zhaquirks.tuya.ts0021.TS0021,
ZCL_TUYA_BUTTON_2_SINGLE_PRESS,
"btn_2_pressed",
2,
"single",
0x00,
),
(
zhaquirks.tuya.ts0021.TS0021,
ZCL_TUYA_BUTTON_2_DOUBLE_PRESS,
"btn_2_pressed",
2,
"double",
0x01,
),
(
zhaquirks.tuya.ts0021.TS0021,
ZCL_TUYA_BUTTON_2_LONG_PRESS,
"btn_2_pressed",
2,
"long",
0x02,
),
),
)
async def test_ts0021_switch(
zigpy_device_from_quirk, quirk, raw_event, expected_attr_name, expected_attr_value
zigpy_device_from_quirk,
quirk,
raw_event,
button_number,
press_type,
expected_attr_value,
):
"""Test tuya TS0021 2-gang switch."""

device = zigpy_device_from_quirk(quirk)

tuya_cluster = device.endpoints[1].tuya_manufacturer
switch_listener = ClusterListener(tuya_cluster)
listener = mock.MagicMock()
tuya_cluster.add_listener(listener)

hdr, args = tuya_cluster.deserialize(raw_event)
tuya_cluster.handle_message(hdr, args)

assert len(switch_listener.cluster_commands) == 1
assert len(switch_listener.attribute_updates) == 1

assert switch_listener.attribute_updates[0][0] == expected_attr_name
assert switch_listener.attribute_updates[0][0] == f"btn_{button_number}_pressed"
assert switch_listener.attribute_updates[0][1] == expected_attr_value

# We fire two events:
# - One for the attribute update;
# - One for the button press.
assert listener.zha_send_event.mock_calls == [
mock.call(
"attribute_updated",
{
"attribute_id": f"btn_{button_number}_pressed",
"attribute_name": "Unknown",
"value": expected_attr_value,
},
),
mock.call(
f"button_{button_number}_{press_type}_press",
{
"button": button_number,
"press_type": press_type,
},
),
]


@pytest.mark.parametrize("quirk", (zhaquirks.tuya.ts0601_switch.TuyaDoubleSwitchTO,))
async def test_doubleswitch_state_report(zigpy_device_from_quirk, quirk):
Expand Down
25 changes: 22 additions & 3 deletions zhaquirks/tuya/ts0021.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@
SHORT_PRESS,
VALUE,
)
from zhaquirks.tuya import TUYA_CLUSTER_ID, DPToAttributeMapping, TuyaNewManufCluster
from zhaquirks.tuya import (
TUYA_CLUSTER_ID,
DPToAttributeMapping,
TuyaDatapointData,
TuyaNewManufCluster,
)

BTN_1 = "Button 1"
BTN_2 = "Button 2"
Expand All @@ -36,6 +41,8 @@
class TuyaCustomCluster(TuyaNewManufCluster, EventableCluster):
"""Tuya Custom Cluster for mapping data points to attributes."""

PRESS_TYPE = {0: "single", 1: "double", 2: "long"}

dp_to_attribute: dict[int, DPToAttributeMapping] = {
1: DPToAttributeMapping(
TuyaNewManufCluster.ep_attribute,
Expand All @@ -52,6 +59,20 @@ class TuyaCustomCluster(TuyaNewManufCluster, EventableCluster):
2: "_dp_2_attr_update",
}

def _dp_2_attr_update(self, datapoint: TuyaDatapointData) -> None:
super()._dp_2_attr_update(datapoint)
button_n = datapoint.dp
press_type = self.PRESS_TYPE.get(datapoint.data.payload, "unknown")
action = f"button_{button_n}_{press_type}_press"
self.listener_event(
"zha_send_event",
action,
{
"button": button_n,
"press_type": press_type,
},
)


class TS0021(CustomDevice):
"""Tuya TS0021 2-button switch device."""
Expand Down Expand Up @@ -87,8 +108,6 @@ class TS0021(CustomDevice):
DEVICE_TYPE: zha.DeviceType.IAS_ZONE,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
IasZone.cluster_id,
TuyaCustomCluster,
],
OUTPUT_CLUSTERS: [
Expand Down
Loading