Esempio n. 1
0
async def test_report_values_psbzs(zigpy_device_from_quirk, quirk):
    """Test receiving attributes from PARKSIDE water valve."""

    water_valve_dev = zigpy_device_from_quirk(quirk)
    tuya_cluster = water_valve_dev.endpoints[1].tuya_manufacturer
    tuya_listener = ClusterListener(tuya_cluster)

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

    frames = (
        b"\x09\x5D\x02\x00\x4C\x06\x02\x00\x04\x00\x00\x00\x04",  # time left 4min
        b"\x09\x5D\x02\x00\x4C\x06\x02\x00\x04\x00\x00\x02\x57",  # time left max 599min
        b"\x09\x56\x02\x00\x21\x6C\x01\x00\x01\x01",  # frost lock active
        b"\x09\x56\x02\x00\x21\x6C\x01\x00\x01\x00",  # frost lock inactive
    )
    for frame in frames:
        hdr, args = tuya_cluster.deserialize(frame)
        tuya_cluster.handle_message(hdr, args)

    assert len(tuya_listener.attribute_updates) == 4
    assert tuya_listener.attribute_updates[0][0] == 0xEF12
    assert tuya_listener.attribute_updates[0][1] == 4
    assert tuya_listener.attribute_updates[1][0] == 0xEF12
    assert tuya_listener.attribute_updates[1][1] == 599
    assert tuya_listener.attribute_updates[2][0] == 0xEF13
    assert tuya_listener.attribute_updates[2][1] == 0  # frost lock state is inverted
    assert tuya_listener.attribute_updates[3][0] == 0xEF13
    assert tuya_listener.attribute_updates[3][1] == 1  # frost lock state is inverted
Esempio n. 2
0
async def test_motion(zigpy_device_from_quirk, quirk):
    """Test tuya motion sensor."""

    motion_dev = zigpy_device_from_quirk(quirk)

    motion_cluster = motion_dev.endpoints[1].ias_zone
    motion_listener = ClusterListener(motion_cluster)

    tuya_cluster = motion_dev.endpoints[1].tuya_manufacturer

    # send motion on Tuya manufacturer specific cluster
    hdr, args = tuya_cluster.deserialize(ZCL_TUYA_MOTION)
    with mock.patch.object(motion_cluster, "reset_s", 0):
        tuya_cluster.handle_message(hdr, args)

    assert len(motion_listener.cluster_commands) == 1
    assert len(motion_listener.attribute_updates) == 1
    assert motion_listener.cluster_commands[0][1] == ZONE_STATE
    assert motion_listener.cluster_commands[0][2][0] == ON

    await asyncio.gather(asyncio.sleep(0), asyncio.sleep(0), asyncio.sleep(0))

    assert len(motion_listener.cluster_commands) == 2
    assert motion_listener.cluster_commands[1][1] == ZONE_STATE
    assert motion_listener.cluster_commands[1][2][0] == OFF
Esempio n. 3
0
async def test_tuya_receive_attribute(zigpy_device_from_quirk, quirk):
    """Test conversion of tuya commands to attributes."""

    test_dev = zigpy_device_from_quirk(quirk)
    tuya_cluster = test_dev.endpoints[1].tuya_manufacturer
    listener = ClusterListener(tuya_cluster)

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

    assert len(listener.attribute_updates) == 1
    assert listener.attribute_updates[0][0] == 617
    assert listener.attribute_updates[0][1] == 179
async def test_konke_motion(zigpy_device_from_quirk, quirk):
    """Test konke motion sensor."""

    motion_dev = zigpy_device_from_quirk(quirk)

    motion_cluster = motion_dev.endpoints[1].ias_zone
    motion_listener = ClusterListener(motion_cluster)

    occupancy_cluster = motion_dev.endpoints[1].occupancy
    occupancy_listener = ClusterListener(occupancy_cluster)

    p1 = mock.patch.object(motion_cluster, "reset_s", 0)
    p2 = mock.patch.object(occupancy_cluster, "reset_s", 0)
    # send motion on IAS zone command
    hdr, args = motion_cluster.deserialize(ZCL_IAS_MOTION_COMMAND)
    with p1, p2:
        motion_cluster.handle_message(hdr, args)

    assert len(motion_listener.cluster_commands) == 1
    assert len(motion_listener.attribute_updates) == 0
    assert motion_listener.cluster_commands[0][1] == ZONE_STATE
    assert motion_listener.cluster_commands[0][2][0] == ON

    assert len(occupancy_listener.cluster_commands) == 0
    assert len(occupancy_listener.attribute_updates) == 1
    assert occupancy_listener.attribute_updates[0][0] == 0x0000
    assert occupancy_listener.attribute_updates[0][1] == 1

    await asyncio.sleep(0.1)

    assert len(motion_listener.cluster_commands) == 2
    assert motion_listener.cluster_commands[1][1] == ZONE_STATE
    assert motion_listener.cluster_commands[1][2][0] == OFF

    assert len(occupancy_listener.cluster_commands) == 0
    assert len(occupancy_listener.attribute_updates) == 2
    assert occupancy_listener.attribute_updates[1][0] == 0x0000
    assert occupancy_listener.attribute_updates[1][1] == 0
Esempio n. 5
0
async def test_siren_state_report(zigpy_device_from_quirk, quirk):
    """Test tuya siren standard state reporting from incoming commands."""

    siren_dev = zigpy_device_from_quirk(quirk)
    tuya_cluster = siren_dev.endpoints[1].tuya_manufacturer

    temp_listener = ClusterListener(siren_dev.endpoints[1].temperature)
    humid_listener = ClusterListener(siren_dev.endpoints[1].humidity)
    switch_listener = ClusterListener(siren_dev.endpoints[1].on_off)

    frames = (
        ZCL_TUYA_SIREN_TEMPERATURE,
        ZCL_TUYA_SIREN_HUMIDITY,
        ZCL_TUYA_SIREN_ON,
        ZCL_TUYA_SIREN_OFF,
    )
    for frame in frames:
        hdr, args = tuya_cluster.deserialize(frame)
        tuya_cluster.handle_message(hdr, args)

    assert len(temp_listener.cluster_commands) == 0
    assert len(temp_listener.attribute_updates) == 1
    assert temp_listener.attribute_updates[0][0] == 0x0000
    assert temp_listener.attribute_updates[0][1] == 1790

    assert len(humid_listener.cluster_commands) == 0
    assert len(humid_listener.attribute_updates) == 1
    assert humid_listener.attribute_updates[0][0] == 0x0000
    assert humid_listener.attribute_updates[0][1] == 8500

    assert len(switch_listener.cluster_commands) == 0
    assert len(switch_listener.attribute_updates) == 2
    assert switch_listener.attribute_updates[0][0] == 0x0000
    assert switch_listener.attribute_updates[0][1] == ON
    assert switch_listener.attribute_updates[1][0] == 0x0000
    assert switch_listener.attribute_updates[1][1] == OFF
Esempio n. 6
0
async def test_doubledimmer_state_report(zigpy_device_from_quirk, quirk):
    """Test tuya double switch."""

    TUYA_EP2_DIMM_1 = b"\tV\x02\x01y\x08\x02\x00\x04\x00\x00\x02\xc5"
    TUYA_EP2_DIMM_2 = b"\tW\x02\x01z\x08\x02\x00\x04\x00\x00\x02\x9e"

    dimmer_dev = zigpy_device_from_quirk(quirk)

    dimmer1_cluster = dimmer_dev.endpoints[1].level
    dimmer1_listener = ClusterListener(dimmer1_cluster)

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

    tuya_cluster = dimmer_dev.endpoints[1].tuya_manufacturer

    assert len(dimmer1_listener.cluster_commands) == 0
    assert len(dimmer1_listener.attribute_updates) == 0
    assert len(dimmer2_listener.cluster_commands) == 0
    assert len(dimmer2_listener.attribute_updates) == 0

    # events from channel 2 updates only EP 2
    hdr, args = tuya_cluster.deserialize(TUYA_EP2_DIMM_1)
    tuya_cluster.handle_message(hdr, args)
    assert len(dimmer1_listener.attribute_updates) == 0
    assert len(dimmer2_listener.attribute_updates) == 1
    assert dimmer2_listener.attribute_updates[0][0] == 0x0000
    assert dimmer2_listener.attribute_updates[0][1] == 180

    # events from channel 1 updates only EP 1
    hdr, args = tuya_cluster.deserialize(TUYA_EP2_DIMM_2)
    tuya_cluster.handle_message(hdr, args)
    assert len(dimmer1_listener.attribute_updates) == 0
    assert len(dimmer2_listener.attribute_updates) == 2
    assert dimmer2_listener.attribute_updates[1][0] == 0x0000
    assert dimmer2_listener.attribute_updates[1][1] == 170
Esempio n. 7
0
async def test_valve_state_report(zigpy_device_from_quirk, quirk):
    """Test thermostatic valves standard reporting from incoming commands."""

    valve_dev = zigpy_device_from_quirk(quirk)
    tuya_cluster = valve_dev.endpoints[1].tuya_manufacturer

    thermostat_listener = ClusterListener(valve_dev.endpoints[1].thermostat)

    frames = (
        ZCL_TUYA_VALVE_TEMPERATURE,
        ZCL_TUYA_VALVE_TARGET_TEMP,
        ZCL_TUYA_VALVE_OFF,
        ZCL_TUYA_VALVE_SCHEDULE,
        ZCL_TUYA_VALVE_MANUAL,
    )
    for frame in frames:
        hdr, args = tuya_cluster.deserialize(frame)
        tuya_cluster.handle_message(hdr, args)

    assert len(thermostat_listener.cluster_commands) == 0
    assert len(thermostat_listener.attribute_updates) == 13
    assert thermostat_listener.attribute_updates[0][0] == 0x0000  # TEMP
    assert thermostat_listener.attribute_updates[0][1] == 1790
    assert thermostat_listener.attribute_updates[1][0] == 0x0012  # TARGET
    assert thermostat_listener.attribute_updates[1][1] == 500
    assert thermostat_listener.attribute_updates[2][0] == 0x001C  # OFF
    assert thermostat_listener.attribute_updates[2][1] == 0x00
    assert thermostat_listener.attribute_updates[3][0] == 0x001E
    assert thermostat_listener.attribute_updates[3][1] == 0x00
    assert thermostat_listener.attribute_updates[4][0] == 0x0029
    assert thermostat_listener.attribute_updates[4][1] == 0x00
    assert thermostat_listener.attribute_updates[5][0] == 0x001C  # SCHEDULE
    assert thermostat_listener.attribute_updates[5][1] == 0x04
    assert thermostat_listener.attribute_updates[6][0] == 0x0025
    assert thermostat_listener.attribute_updates[6][1] == 0x01
    assert thermostat_listener.attribute_updates[7][0] == 0x001E
    assert thermostat_listener.attribute_updates[7][1] == 0x04
    assert thermostat_listener.attribute_updates[8][0] == 0x0029
    assert thermostat_listener.attribute_updates[8][1] == 0x01
    assert thermostat_listener.attribute_updates[9][0] == 0x001C  # MANUAL
    assert thermostat_listener.attribute_updates[9][1] == 0x04
    assert thermostat_listener.attribute_updates[10][0] == 0x0025
    assert thermostat_listener.attribute_updates[10][1] == 0x00
    assert thermostat_listener.attribute_updates[11][0] == 0x001E
    assert thermostat_listener.attribute_updates[11][1] == 0x04
    assert thermostat_listener.attribute_updates[12][0] == 0x0029
    assert thermostat_listener.attribute_updates[12][1] == 0x01
Esempio n. 8
0
async def test_eheating_state_report(zigpy_device_from_quirk, quirk):
    """Test thermostatic valves standard reporting from incoming commands."""

    electric_dev = zigpy_device_from_quirk(quirk)
    tuya_cluster = electric_dev.endpoints[1].tuya_manufacturer

    thermostat_listener = ClusterListener(electric_dev.endpoints[1].thermostat)

    frames = (ZCL_TUYA_EHEAT_TEMPERATURE, ZCL_TUYA_EHEAT_TARGET_TEMP)
    for frame in frames:
        hdr, args = tuya_cluster.deserialize(frame)
        tuya_cluster.handle_message(hdr, args)

    assert len(thermostat_listener.cluster_commands) == 0
    assert len(thermostat_listener.attribute_updates) == 2
    assert thermostat_listener.attribute_updates[0][0] == 0x0000  # TEMP
    assert thermostat_listener.attribute_updates[0][1] == 1790
    assert thermostat_listener.attribute_updates[1][0] == 0x0012  # TARGET
    assert thermostat_listener.attribute_updates[1][1] == 2100
Esempio n. 9
0
async def test_singleswitch_state_report(zigpy_device_from_quirk, quirk):
    """Test tuya single switch."""

    switch_dev = zigpy_device_from_quirk(quirk)

    switch_cluster = switch_dev.endpoints[1].on_off
    switch_listener = ClusterListener(switch_cluster)

    tuya_cluster = switch_dev.endpoints[1].tuya_manufacturer

    hdr, args = tuya_cluster.deserialize(ZCL_TUYA_SWITCH_ON)
    tuya_cluster.handle_message(hdr, args)
    hdr, args = tuya_cluster.deserialize(ZCL_TUYA_SWITCH_OFF)
    tuya_cluster.handle_message(hdr, args)

    assert len(switch_listener.cluster_commands) == 0
    assert len(switch_listener.attribute_updates) == 2
    assert switch_listener.attribute_updates[0][0] == 0x0000
    assert switch_listener.attribute_updates[0][1] == ON
    assert switch_listener.attribute_updates[1][0] == 0x0000
    assert switch_listener.attribute_updates[1][1] == OFF
Esempio n. 10
0
async def test_tuya_version(zigpy_device_from_quirk, quirk):
    """Test TUYA_MCU_VERSION_RSP messages."""

    tuya_device = zigpy_device_from_quirk(quirk)

    tuya_cluster = tuya_device.endpoints[1].tuya_manufacturer
    cluster_listener = ClusterListener(tuya_cluster)

    assert len(cluster_listener.attribute_updates) == 0

    # simulate a TUYA_MCU_VERSION_RSP message
    hdr, args = tuya_cluster.deserialize(ZCL_TUYA_VERSION_RSP)
    assert hdr.command_id == TUYA_MCU_VERSION_RSP

    tuya_cluster.handle_message(hdr, args)
    assert len(cluster_listener.attribute_updates) == 1
    assert cluster_listener.attribute_updates[0][0] == ATTR_MCU_VERSION
    assert cluster_listener.attribute_updates[0][1] == "2.0.2"

    # read 'mcu_version' from cluster's attributes
    succ, fail = await tuya_cluster.read_attributes(("mcu_version",))
    assert succ["mcu_version"] == "2.0.2"
Esempio n. 11
0
async def test_command(zigpy_device_from_quirk, quirk):
    """Test write cluster attributes."""

    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
    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:
        status = await switch2_cluster.command(0x0001)

        m1.assert_called_with(
            61184,
            2,
            b"\x01\x02\x00\x00\x01\x07\x01\x00\x01\x01",
            expect_reply=True,
            command_id=0,
        )
        assert status == foundation.Status.SUCCESS

        status = await dimmer1_cluster.command(0x0000, 225)

        m1.assert_called_with(
            61184,
            4,
            b"\x01\x04\x00\x00\x03\x02\x02\x00\x04\x00\x00\x03r",
            expect_reply=True,
            command_id=0,
        )
        assert status == foundation.Status.SUCCESS
Esempio n. 12
0
async def test_command_psbzs(zigpy_device_from_quirk, quirk):
    """Test executing cluster commands for PARKSIDE water valve."""

    water_valve_dev = zigpy_device_from_quirk(quirk)
    tuya_cluster = water_valve_dev.endpoints[1].tuya_manufacturer
    switch_cluster = water_valve_dev.endpoints[1].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 switch_cluster.command(0x0001)

        m1.assert_called_with(
            61184,
            2,
            b"\x01\x02\x00\x00\x01\x01\x01\x00\x01\x01",
            expect_reply=True,
            command_id=0,
        )
        assert rsp.status == foundation.Status.SUCCESS
Esempio n. 13
0
async def test_moes(zigpy_device_from_quirk, quirk):
    """Test thermostatic valve outgoing commands."""

    valve_dev = zigpy_device_from_quirk(quirk)
    tuya_cluster = valve_dev.endpoints[1].tuya_manufacturer
    thermostat_cluster = valve_dev.endpoints[1].thermostat
    onoff_cluster = valve_dev.endpoints[1].on_off
    thermostat_ui_cluster = valve_dev.endpoints[1].thermostat_ui

    thermostat_listener = ClusterListener(valve_dev.endpoints[1].thermostat)
    onoff_listener = ClusterListener(valve_dev.endpoints[1].on_off)

    frames = (
        ZCL_TUYA_VALVE_TEMPERATURE,
        ZCL_TUYA_VALVE_WINDOW_DETECTION,
        ZCL_TUYA_VALVE_WORKDAY_SCHEDULE,
        ZCL_TUYA_VALVE_WEEKEND_SCHEDULE,
        ZCL_TUYA_VALVE_OFF,
        ZCL_TUYA_VALVE_SCHEDULE,
        ZCL_TUYA_VALVE_MANUAL,
        ZCL_TUYA_VALVE_COMFORT,
        ZCL_TUYA_VALVE_ECO,
        ZCL_TUYA_VALVE_BOOST,
        ZCL_TUYA_VALVE_COMPLEX,
        ZCL_TUYA_VALVE_STATE_50,
    )
    for frame in frames:
        hdr, args = tuya_cluster.deserialize(frame)
        tuya_cluster.handle_message(hdr, args)

    assert len(thermostat_listener.cluster_commands) == 0
    assert len(thermostat_listener.attribute_updates) == 61
    assert thermostat_listener.attribute_updates[0][0] == 0x0000
    assert thermostat_listener.attribute_updates[0][1] == 1790
    assert thermostat_listener.attribute_updates[1][0] == 0x4110
    assert thermostat_listener.attribute_updates[1][1] == 6
    assert thermostat_listener.attribute_updates[2][0] == 0x4111
    assert thermostat_listener.attribute_updates[2][1] == 0
    assert thermostat_listener.attribute_updates[3][0] == 0x4112
    assert thermostat_listener.attribute_updates[3][1] == 2000
    assert thermostat_listener.attribute_updates[4][0] == 0x4120
    assert thermostat_listener.attribute_updates[4][1] == 8
    assert thermostat_listener.attribute_updates[5][0] == 0x4121
    assert thermostat_listener.attribute_updates[5][1] == 0
    assert thermostat_listener.attribute_updates[6][0] == 0x4122
    assert thermostat_listener.attribute_updates[6][1] == 1500
    assert thermostat_listener.attribute_updates[7][0] == 0x4130
    assert thermostat_listener.attribute_updates[7][1] == 11
    assert thermostat_listener.attribute_updates[8][0] == 0x4131
    assert thermostat_listener.attribute_updates[8][1] == 30
    assert thermostat_listener.attribute_updates[9][0] == 0x4132
    assert thermostat_listener.attribute_updates[9][1] == 1500
    assert thermostat_listener.attribute_updates[10][0] == 0x4140
    assert thermostat_listener.attribute_updates[10][1] == 12
    assert thermostat_listener.attribute_updates[11][0] == 0x4141
    assert thermostat_listener.attribute_updates[11][1] == 30
    assert thermostat_listener.attribute_updates[12][0] == 0x4142
    assert thermostat_listener.attribute_updates[12][1] == 1500
    assert thermostat_listener.attribute_updates[13][0] == 0x4150
    assert thermostat_listener.attribute_updates[13][1] == 17
    assert thermostat_listener.attribute_updates[14][0] == 0x4151
    assert thermostat_listener.attribute_updates[14][1] == 30
    assert thermostat_listener.attribute_updates[15][0] == 0x4152
    assert thermostat_listener.attribute_updates[15][1] == 2000
    assert thermostat_listener.attribute_updates[16][0] == 0x4160
    assert thermostat_listener.attribute_updates[16][1] == 22
    assert thermostat_listener.attribute_updates[17][0] == 0x4161
    assert thermostat_listener.attribute_updates[17][1] == 0
    assert thermostat_listener.attribute_updates[18][0] == 0x4162
    assert thermostat_listener.attribute_updates[18][1] == 1500
    assert thermostat_listener.attribute_updates[19][0] == 0x4210
    assert thermostat_listener.attribute_updates[19][1] == 6
    assert thermostat_listener.attribute_updates[20][0] == 0x4211
    assert thermostat_listener.attribute_updates[20][1] == 0
    assert thermostat_listener.attribute_updates[21][0] == 0x4212
    assert thermostat_listener.attribute_updates[21][1] == 2000
    assert thermostat_listener.attribute_updates[22][0] == 0x4220
    assert thermostat_listener.attribute_updates[22][1] == 8
    assert thermostat_listener.attribute_updates[23][0] == 0x4221
    assert thermostat_listener.attribute_updates[23][1] == 0
    assert thermostat_listener.attribute_updates[24][0] == 0x4222
    assert thermostat_listener.attribute_updates[24][1] == 1500
    assert thermostat_listener.attribute_updates[25][0] == 0x4230
    assert thermostat_listener.attribute_updates[25][1] == 11
    assert thermostat_listener.attribute_updates[26][0] == 0x4231
    assert thermostat_listener.attribute_updates[26][1] == 30
    assert thermostat_listener.attribute_updates[27][0] == 0x4232
    assert thermostat_listener.attribute_updates[27][1] == 1500
    assert thermostat_listener.attribute_updates[28][0] == 0x4240
    assert thermostat_listener.attribute_updates[28][1] == 12
    assert thermostat_listener.attribute_updates[29][0] == 0x4241
    assert thermostat_listener.attribute_updates[29][1] == 30
    assert thermostat_listener.attribute_updates[30][0] == 0x4242
    assert thermostat_listener.attribute_updates[30][1] == 1500
    assert thermostat_listener.attribute_updates[31][0] == 0x4250
    assert thermostat_listener.attribute_updates[31][1] == 17
    assert thermostat_listener.attribute_updates[32][0] == 0x4251
    assert thermostat_listener.attribute_updates[32][1] == 30
    assert thermostat_listener.attribute_updates[33][0] == 0x4252
    assert thermostat_listener.attribute_updates[33][1] == 2000
    assert thermostat_listener.attribute_updates[34][0] == 0x4260
    assert thermostat_listener.attribute_updates[34][1] == 22
    assert thermostat_listener.attribute_updates[35][0] == 0x4261
    assert thermostat_listener.attribute_updates[35][1] == 0
    assert thermostat_listener.attribute_updates[36][0] == 0x4262
    assert thermostat_listener.attribute_updates[36][1] == 1500
    assert thermostat_listener.attribute_updates[37][0] == 0x4002
    assert thermostat_listener.attribute_updates[37][1] == 0
    assert thermostat_listener.attribute_updates[38][0] == 0x0025
    assert thermostat_listener.attribute_updates[38][1] == 0
    assert thermostat_listener.attribute_updates[39][0] == 0x0002
    assert thermostat_listener.attribute_updates[39][1] == 0
    assert thermostat_listener.attribute_updates[40][0] == 0x4002
    assert thermostat_listener.attribute_updates[40][1] == 1
    assert thermostat_listener.attribute_updates[41][0] == 0x0025
    assert thermostat_listener.attribute_updates[41][1] == 1
    assert thermostat_listener.attribute_updates[42][0] == 0x0002
    assert thermostat_listener.attribute_updates[42][1] == 1
    assert thermostat_listener.attribute_updates[43][0] == 0x4002
    assert thermostat_listener.attribute_updates[43][1] == 2
    assert thermostat_listener.attribute_updates[44][0] == 0x0025
    assert thermostat_listener.attribute_updates[44][1] == 0
    assert thermostat_listener.attribute_updates[45][0] == 0x0002
    assert thermostat_listener.attribute_updates[45][1] == 1
    assert thermostat_listener.attribute_updates[46][0] == 0x4002
    assert thermostat_listener.attribute_updates[46][1] == 3
    assert thermostat_listener.attribute_updates[47][0] == 0x0025
    assert thermostat_listener.attribute_updates[47][1] == 0
    assert thermostat_listener.attribute_updates[48][0] == 0x0002
    assert thermostat_listener.attribute_updates[48][1] == 1
    assert thermostat_listener.attribute_updates[49][0] == 0x4002
    assert thermostat_listener.attribute_updates[49][1] == 4
    assert thermostat_listener.attribute_updates[50][0] == 0x0025
    assert thermostat_listener.attribute_updates[50][1] == 4
    assert thermostat_listener.attribute_updates[51][0] == 0x0002
    assert thermostat_listener.attribute_updates[51][1] == 1
    assert thermostat_listener.attribute_updates[52][0] == 0x4002
    assert thermostat_listener.attribute_updates[52][1] == 5
    assert thermostat_listener.attribute_updates[53][0] == 0x0025
    assert thermostat_listener.attribute_updates[53][1] == 0
    assert thermostat_listener.attribute_updates[54][0] == 0x0002
    assert thermostat_listener.attribute_updates[54][1] == 1
    assert thermostat_listener.attribute_updates[55][0] == 0x4002
    assert thermostat_listener.attribute_updates[55][1] == 6
    assert thermostat_listener.attribute_updates[56][0] == 0x0025
    assert thermostat_listener.attribute_updates[56][1] == 0
    assert thermostat_listener.attribute_updates[57][0] == 0x0002
    assert thermostat_listener.attribute_updates[57][1] == 1
    assert thermostat_listener.attribute_updates[58][0] == 0x4004
    assert thermostat_listener.attribute_updates[58][1] == 50
    assert thermostat_listener.attribute_updates[59][0] == 0x001E
    assert thermostat_listener.attribute_updates[59][1] == 4
    assert thermostat_listener.attribute_updates[60][0] == 0x0029
    assert thermostat_listener.attribute_updates[60][1] == 1

    assert len(onoff_listener.cluster_commands) == 0
    assert len(onoff_listener.attribute_updates) == 3
    assert onoff_listener.attribute_updates[0][0] == 0x6001
    assert onoff_listener.attribute_updates[0][1] == 5
    assert onoff_listener.attribute_updates[1][0] == 0x6000
    assert onoff_listener.attribute_updates[1][1] == 1600
    assert onoff_listener.attribute_updates[2][0] == 0x0000  # TARGET
    assert onoff_listener.attribute_updates[2][1] == 1

    thermostat_ui_listener = ClusterListener(valve_dev.endpoints[1].thermostat_ui)
    power_listener = ClusterListener(valve_dev.endpoints[1].power)

    frames = (
        ZCL_TUYA_VALVE_CHILD_LOCK_ON,
        ZCL_TUYA_VALVE_AUTO_LOCK_ON,
        ZCL_TUYA_VALVE_BATTERY_LOW,
    )
    for frame in frames:
        hdr, args = tuya_cluster.deserialize(frame)
        tuya_cluster.handle_message(hdr, args)

    assert len(thermostat_ui_listener.cluster_commands) == 0
    assert len(thermostat_ui_listener.attribute_updates) == 2
    assert thermostat_ui_listener.attribute_updates[0][0] == 0x0001
    assert thermostat_ui_listener.attribute_updates[0][1] == 1
    assert thermostat_ui_listener.attribute_updates[1][0] == 0x5000
    assert thermostat_ui_listener.attribute_updates[1][1] == 1

    assert len(power_listener.cluster_commands) == 0
    assert len(power_listener.attribute_updates) == 1
    assert power_listener.attribute_updates[0][0] == 0x0021
    assert power_listener.attribute_updates[0][1] == 10

    async def async_success(*args, **kwargs):
        return foundation.Status.SUCCESS

    with mock.patch.object(
        tuya_cluster.endpoint, "request", side_effect=async_success
    ) as m1:

        status = await thermostat_cluster.write_attributes(
            {
                "occupied_heating_setpoint": 2500,
            }
        )
        m1.assert_called_with(
            61184,
            1,
            b"\x01\x01\x00\x00\x01\x02\x02\x00\x04\x00\x00\x00\xfa",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "operation_preset": 0x00,
            }
        )
        m1.assert_called_with(
            61184,
            2,
            b"\x01\x02\x00\x00\x02\x04\x04\x00\x01\x00",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "operation_preset": 0x02,
            }
        )
        m1.assert_called_with(
            61184,
            3,
            b"\x01\x03\x00\x00\x03\x04\x04\x00\x01\x02",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        # simulate a target temp update so that relative changes can work
        hdr, args = tuya_cluster.deserialize(ZCL_TUYA_VALVE_TARGET_TEMP)
        tuya_cluster.handle_message(hdr, args)
        status = await thermostat_cluster.command(0x0000, 0x00, 20)
        m1.assert_called_with(
            61184,
            4,
            b"\x01\x04\x00\x00\x04\x02\x02\x00\x04\x00\x00\x00F",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await onoff_cluster.write_attributes(
            {
                "on_off": 0x00,
                "window_detection_timeout_minutes": 0x02,
                "window_detection_temperature": 2000,
            }
        )
        m1.assert_called_with(
            61184,
            5,
            b"\x01\x05\x00\x00\x05\x68\x00\x00\x03\x00\x14\x02",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "occupancy": 0x00,
            }
        )
        m1.assert_called_with(
            61184,
            6,
            b"\x01\x06\x00\x00\x06\x04\x04\x00\x01\x00",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "occupancy": 0x01,
                "programing_oper_mode": 0x00,
            }
        )
        m1.assert_called_with(
            61184,
            7,
            b"\x01\x07\x00\x00\x07\x04\x04\x00\x01\x02",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "programing_oper_mode": 0x01,
            }
        )
        m1.assert_called_with(
            61184,
            8,
            b"\x01\x08\x00\x00\x08\x04\x04\x00\x01\x01",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "programing_oper_mode": 0x04,
            }
        )
        m1.assert_called_with(
            61184,
            9,
            b"\x01\x09\x00\x00\x09\x04\x04\x00\x01\x04",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "workday_schedule_1_temperature": 1700,
            }
        )
        m1.assert_called_with(
            61184,
            10,
            b"\x01\x0A\x00\x00\x0A\x70\x00\x00\x12\x06\x00\x11\x08\x00\x0F\x0B\x1E\x0F\x0C\x1E\x0F\x11\x1E\x14\x16\x00\x0F",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "workday_schedule_1_minute": 45,
            }
        )
        m1.assert_called_with(
            61184,
            11,
            b"\x01\x0B\x00\x00\x0B\x70\x00\x00\x12\x06\x2D\x14\x08\x00\x0F\x0B\x1E\x0F\x0C\x1E\x0F\x11\x1E\x14\x16\x00\x0F",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "workday_schedule_1_hour": 5,
            }
        )
        m1.assert_called_with(
            61184,
            12,
            b"\x01\x0C\x00\x00\x0C\x70\x00\x00\x12\x05\x00\x14\x08\x00\x0F\x0B\x1E\x0F\x0C\x1E\x0F\x11\x1E\x14\x16\x00\x0F",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "weekend_schedule_1_temperature": 1700,
            }
        )
        m1.assert_called_with(
            61184,
            13,
            b"\x01\x0D\x00\x00\x0D\x71\x00\x00\x12\x06\x00\x11\x08\x00\x0F\x0B\x1E\x0F\x0C\x1E\x0F\x11\x1E\x14\x16\x00\x0F",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "weekend_schedule_1_minute": 45,
            }
        )
        m1.assert_called_with(
            61184,
            14,
            b"\x01\x0E\x00\x00\x0E\x71\x00\x00\x12\x06\x2D\x14\x08\x00\x0F\x0B\x1E\x0F\x0C\x1E\x0F\x11\x1E\x14\x16\x00\x0F",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "weekend_schedule_1_hour": 5,
            }
        )
        m1.assert_called_with(
            61184,
            15,
            b"\x01\x0F\x00\x00\x0F\x71\x00\x00\x12\x05\x00\x14\x08\x00\x0F\x0B\x1E\x0F\x0C\x1E\x0F\x11\x1E\x14\x16\x00\x0F",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.write_attributes(
            {
                "system_mode": 0x01,
            }
        )
        m1.assert_called_with(
            61184,
            16,
            b"\x01\x10\x00\x00\x10\x04\x04\x00\x01\x06",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_ui_cluster.write_attributes(
            {
                "auto_lock": 0x00,
            }
        )
        m1.assert_called_with(
            61184,
            17,
            b"\x01\x11\x00\x00\x11\x74\x01\x00\x01\x00",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await onoff_cluster.command(0x0000)
        m1.assert_called_with(
            61184,
            18,
            b"\x01\x12\x00\x00\x12\x68\x00\x00\x03\x00\x10\x05",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await onoff_cluster.command(0x0001)
        m1.assert_called_with(
            61184,
            19,
            b"\x01\x13\x00\x00\x13\x68\x00\x00\x03\x01\x10\x05",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await onoff_cluster.command(0x0002)
        m1.assert_called_with(
            61184,
            20,
            b"\x01\x14\x00\x00\x14\x68\x00\x00\x03\x00\x10\x05",
            expect_reply=False,
            command_id=0,
        )
        assert status == (foundation.Status.SUCCESS,)

        status = await onoff_cluster.write_attributes({})
        assert status == (foundation.Status.SUCCESS,)

        status = await thermostat_cluster.command(0x0002)
        assert status == foundation.Status.UNSUP_CLUSTER_COMMAND

        status = await onoff_cluster.command(0x0009)
        assert status == foundation.Status.UNSUP_CLUSTER_COMMAND

        origdatetime = datetime.datetime
        datetime.datetime = NewDatetime

        hdr, args = tuya_cluster.deserialize(ZCL_TUYA_SET_TIME_REQUEST)
        tuya_cluster.handle_message(hdr, args)
        m1.assert_called_with(
            61184,
            21,
            b"\x01\x15\x24\x00\x08\x00\x00\x1C\x20\x00\x00\x0E\x10",
            expect_reply=False,
            command_id=0x0024,
        )
        datetime.datetime = origdatetime
Esempio n. 14
0
async def test_dim_values(zigpy_device_from_quirk, quirk):
    """Test dimming values."""

    dimmer_dev = zigpy_device_from_quirk(quirk)

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

    tuya_cluster = dimmer_dev.endpoints[1].tuya_manufacturer

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

    # payload=553
    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

    succ, fail = await dimmer2_cluster.read_attributes(("current_level", ))
    assert succ["current_level"] == 141

    # payload=700
    hdr, args = tuya_cluster.deserialize(
        b"\tV\x02\x01y\x08\x02\x00\x04\x00\x00\x02\xbc")
    tuya_cluster.handle_message(hdr, args)
    succ, fail = await dimmer2_cluster.read_attributes(("current_level", ))
    assert succ["current_level"] == 178

    # payload=982
    hdr, args = tuya_cluster.deserialize(
        b"\tV\x02\x01y\x08\x02\x00\x04\x00\x00\x03\xd6")
    tuya_cluster.handle_message(hdr, args)
    succ, fail = await dimmer2_cluster.read_attributes(("current_level", ))
    assert succ["current_level"] == 250

    # payload=657
    hdr, args = tuya_cluster.deserialize(
        b"\tV\x02\x01y\x08\x02\x00\x04\x00\x00\x02\x91")
    tuya_cluster.handle_message(hdr, args)
    succ, fail = await dimmer2_cluster.read_attributes(("current_level", ))
    assert succ["current_level"] == 167

    # payload=400
    hdr, args = tuya_cluster.deserialize(
        b"\tV\x02\x01y\x08\x02\x00\x04\x00\x00\x01\x90")
    tuya_cluster.handle_message(hdr, args)
    succ, fail = await dimmer2_cluster.read_attributes(("current_level", ))
    assert succ["current_level"] == 102

    # payload=149
    hdr, args = tuya_cluster.deserialize(
        b"\tV\x02\x01y\x08\x02\x00\x04\x00\x00\x00\x95")
    tuya_cluster.handle_message(hdr, args)
    succ, fail = await dimmer2_cluster.read_attributes(("current_level", ))
    assert succ["current_level"] == 37

    # payload=339
    hdr, args = tuya_cluster.deserialize(
        b"\tV\x02\x01y\x08\x02\x00\x04\x00\x00\x01\x53")
    tuya_cluster.handle_message(hdr, args)
    succ, fail = await dimmer2_cluster.read_attributes(("current_level", ))
    assert succ["current_level"] == 86