Skip to content
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
106 changes: 106 additions & 0 deletions tests/test_tuya_dimmer.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,109 @@ async def test_doubledimmer_state_report(zigpy_device_from_quirk, quirk):
assert len(dimmer2_listener.attribute_updates) == 2
assert dimmer2_listener.attribute_updates[1][0] == 0x0000
assert dimmer2_listener.attribute_updates[1][1] == 170


@pytest.mark.parametrize(
"quirk", (zhaquirks.tuya.ts0601_dimmer.TuyaTripleSwitchDimmer,)
)
async def test_triple_command(zigpy_device_from_quirk, quirk):
"""Test write cluster attributes for triple switch dimmer."""

dimmer_dev = zigpy_device_from_quirk(quirk)
tuya_cluster = dimmer_dev.endpoints[1].tuya_manufacturer
dimmer1_cluster = dimmer_dev.endpoints[1].level
switch2_cluster = dimmer_dev.endpoints[2].on_off
switch3_cluster = dimmer_dev.endpoints[3].on_off
tuya_listener = ClusterListener(tuya_cluster)

assert len(tuya_listener.cluster_commands) == 0
assert len(tuya_listener.attribute_updates) == 0

with mock.patch.object(
tuya_cluster.endpoint, "request", return_value=foundation.Status.SUCCESS
) as m1:
rsp = await switch2_cluster.command(0x0001) # turn_on
await wait_for_zigpy_tasks()

m1.assert_called_with(
cluster=61184,
sequence=1,
data=b"\x01\x01\x00\x00\x01\x07\x01\x00\x01\x01",
command_id=0,
timeout=5,
expect_reply=True,
use_ieee=False,
ask_for_ack=None,
priority=None,
)
assert rsp.status == foundation.Status.SUCCESS

rsp = await switch3_cluster.command(0x0001) # turn_on
await wait_for_zigpy_tasks()

m1.assert_called_with(
cluster=61184,
sequence=2,
data=b"\x01\x02\x00\x00\x02\x0f\x01\x00\x01\x01",
command_id=0,
timeout=5,
expect_reply=True,
use_ieee=False,
ask_for_ack=None,
priority=None,
)
assert rsp.status == foundation.Status.SUCCESS

rsp = await dimmer1_cluster.command(0x0000, 225) # move_to_level
await wait_for_zigpy_tasks()

m1.assert_called_with(
cluster=61184,
sequence=3,
data=b"\x01\x03\x00\x00\x03\x02\x02\x00\x04\x00\x00\x03r",
command_id=0,
timeout=5,
expect_reply=True,
use_ieee=False,
ask_for_ack=None,
priority=None,
)
assert rsp.status == foundation.Status.SUCCESS


@pytest.mark.parametrize(
"quirk", (zhaquirks.tuya.ts0601_dimmer.TuyaTripleSwitchDimmer,)
)
async def test_triple_dim_values(zigpy_device_from_quirk, quirk):
"""Test dimming values for triple switch dimmer."""

dimmer_dev = zigpy_device_from_quirk(quirk)

dimmer2_cluster = dimmer_dev.endpoints[2].level
dimmer2_listener = ClusterListener(dimmer2_cluster)

dimmer3_cluster = dimmer_dev.endpoints[3].level
dimmer3_listener = ClusterListener(dimmer3_cluster)

tuya_cluster = dimmer_dev.endpoints[1].tuya_manufacturer

assert len(dimmer2_listener.attribute_updates) == 0
assert len(dimmer3_listener.attribute_updates) == 0

# Test channel 2 dimming
hdr, args = tuya_cluster.deserialize(
b"\tV\x02\x01y\x08\x02\x00\x04\x00\x00\x02\x29"
)
tuya_cluster.handle_message(hdr, args)
assert len(dimmer2_listener.attribute_updates) == 1
assert dimmer2_listener.attribute_updates[0][0] == 0x0000
assert dimmer2_listener.attribute_updates[0][1] == 141

# Test channel 3 dimming
hdr, args = tuya_cluster.deserialize(
b"\tV\x02\x01y\x10\x02\x00\x04\x00\x00\x02\xbc"
)
tuya_cluster.handle_message(hdr, args)
assert len(dimmer3_listener.attribute_updates) == 1
assert dimmer3_listener.attribute_updates[0][0] == 0x0000
assert dimmer3_listener.attribute_updates[0][1] == 178
63 changes: 63 additions & 0 deletions zhaquirks/tuya/ts0601_dimmer.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class TuyaInWallLevelControlNM(NoManufacturerCluster, TuyaInWallLevelControl):
# --- DEVICE SUMMARY ---
# TuyaSingleSwitchDimmer: 0x00, 0x04, 0x05, 0xEF00; 0x000A, 0x0019
# TuyaDoubleSwitchDimmer: 0x00, 0x04, 0x05, 0xEF00; 0x000A, 0x0019
# TuyaTripleSwitchDimmer: 0x00, 0x04, 0x05, 0xEF00; 0x000A, 0x0019
# - Dimmer with Green Power Proxy: Endpoint=242 profile=41440 device_type=0x0061, output_clusters: 0x0021 -
# TuyaSingleSwitchDimmerGP: 0x00, 0x04, 0x05, 0xEF00; 0x000A, 0x0019
# TuyaDoubleSwitchDimmerGP: 0x00, 0x04, 0x05, 0xEF00; 0x000A, 0x0019
Expand Down Expand Up @@ -144,6 +145,68 @@ class TuyaDoubleSwitchDimmer(TuyaDimmerSwitch):
}


class TuyaTripleSwitchDimmer(TuyaDimmerSwitch):
"""Tuya triple-channel dimmer (TS0601, Zemismart/Moes), non-GP."""

signature = {
MODELS_INFO: [
("_TZE204_znvwzxkq", "TS0601"),
],
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=0x0051
# device_version=1
# input_clusters=[0, 4, 5, 61184]
# output_clusters=[10, 25]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaLevelControlManufCluster.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
},
}

replacement = {
ENDPOINTS: {
1: {
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaLevelControlManufCluster,
TuyaOnOff,
TuyaInWallLevelControl,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
TuyaOnOff,
TuyaInWallLevelControl,
],
OUTPUT_CLUSTERS: [],
},
3: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
TuyaOnOff,
TuyaInWallLevelControl,
],
OUTPUT_CLUSTERS: [],
},
}
}


class TuyaSingleSwitchDimmerGP(TuyaDimmerSwitch):
"""Tuya touch switch device."""

Expand Down
Loading