예제 #1
0
    async def request(
        self,
        device,
        profile,
        cluster,
        src_ep,
        dst_ep,
        sequence,
        data,
        expect_reply=True,
        use_ieee=False,
    ):
        tx_options = c.af.TransmitOptions.RouteDiscovery

        # if expect_reply:
        #    tx_options |= c.af.TransmitOptions.APSAck

        if use_ieee:
            destination = t.AddrModeAddress(mode=t.AddrMode.IEEE,
                                            address=device.ieee)
        else:
            destination = t.AddrModeAddress(mode=t.AddrMode.NWK,
                                            address=device.nwk)

        return await self._send_request(
            dst_addr=destination,
            dst_ep=dst_ep,
            src_ep=src_ep,
            cluster=cluster,
            sequence=sequence,
            options=tx_options,
            radius=30,
            data=data,
        )
예제 #2
0
    async def broadcast(
        self,
        profile,
        cluster,
        src_ep,
        dst_ep,
        grpid,
        radius,
        sequence,
        data,
        broadcast_address=zigpy.types.BroadcastAddress.RX_ON_WHEN_IDLE,
    ):
        assert grpid == 0

        return await self._send_request(
            dst_addr=t.AddrModeAddress(mode=t.AddrMode.Broadcast,
                                       address=broadcast_address),
            dst_ep=dst_ep,
            src_ep=src_ep,
            cluster=cluster,
            sequence=sequence,
            options=c.af.TransmitOptions.NONE,
            radius=radius,
            data=data,
        )
예제 #3
0
def test_command_str_repr():
    command = c.UtilCommands.BindAddEntry.Req(
        DstAddrModeAddr=t.AddrModeAddress(mode=t.AddrMode.NWK, address=0x1234),
        DstEndpoint=0x56,
        ClusterIdList=[0x12, 0x34],
    )

    assert repr(command) == str(command)
    assert str([command]) == f"[{str(command)}]"
예제 #4
0
async def test_zigpy_request(application, mocker):
    app, znp_server = application
    await app.startup(auto_form=False)

    TSN = 1

    device = app.add_device(ieee=t.EUI64(range(8)), nwk=0xAABB)
    device.status = zigpy.device.Status.ENDPOINTS_INIT
    device.initializing = False

    device.add_endpoint(1).add_input_cluster(6)

    # Respond to a light turn on request
    data_req = znp_server.reply_once_to(
        request=c.AF.DataRequestExt.Req(
            DstAddrModeAddress=t.AddrModeAddress(mode=t.AddrMode.NWK,
                                                 address=device.nwk),
            DstEndpoint=1,
            SrcEndpoint=1,
            ClusterId=6,
            TSN=TSN,
            Data=bytes([0x01, TSN, 0x01]),
            partial=True,
        ),
        responses=[
            c.AF.DataRequestExt.Rsp(Status=t.Status.SUCCESS),
            c.AF.DataConfirm.Callback(
                Status=t.Status.SUCCESS,
                Endpoint=1,
                TSN=TSN,
            ),
            c.ZDO.SrcRtgInd.Callback(DstAddr=device.nwk, Relays=[]),
            c.AF.IncomingMsg.Callback(
                GroupId=0x0000,
                ClusterId=6,
                SrcAddr=device.nwk,
                SrcEndpoint=1,
                DstEndpoint=1,
                WasBroadcast=False,
                LQI=63,
                SecurityUse=False,
                TimeStamp=1198515,
                TSN=0,
                Data=bytes([0x08, TSN, 0x0B, 0x00, 0x00]),
                MacSrcAddr=device.nwk,
                MsgResultRadius=29,
            ),
        ],
    )

    # Turn on the light
    await device.endpoints[1].on_off.on()
    await data_req
예제 #5
0
async def test_zigpy_request_failure(application, mocker):
    app, znp_server = application
    await app.startup(auto_form=False)

    TSN = 1

    device = app.add_device(ieee=t.EUI64(range(8)), nwk=0xAABB)
    device.status = zigpy.device.Status.ENDPOINTS_INIT
    device.initializing = False

    device.add_endpoint(1).add_input_cluster(6)

    # Fail to respond to a light turn on request
    znp_server.reply_to(
        request=c.AF.DataRequestExt.Req(
            DstAddrModeAddress=t.AddrModeAddress(mode=t.AddrMode.NWK,
                                                 address=device.nwk),
            DstEndpoint=1,
            SrcEndpoint=1,
            ClusterId=6,
            TSN=TSN,
            Data=bytes([0x01, TSN, 0x01]),
            partial=True,
        ),
        responses=[
            c.AF.DataRequestExt.Rsp(Status=t.Status.SUCCESS),
            c.AF.DataConfirm.Callback(
                Status=t.Status.FAILURE,
                Endpoint=1,
                TSN=TSN,
            ),
        ],
    )

    mocker.patch.object(app,
                        "_send_request",
                        new=CoroutineMock(wraps=app._send_request))

    # Fail to turn on the light
    with pytest.raises(zigpy.exceptions.DeliveryError):
        await device.endpoints[1].on_off.on()

    assert app._send_request.call_count == 1
예제 #6
0
                        "_send_request",
                        new=CoroutineMock(wraps=app._send_request))

    # Fail to turn on the light
    with pytest.raises(zigpy.exceptions.DeliveryError):
        await device.endpoints[1].on_off.on()

    assert app._send_request.call_count == 1


@pytest_mark_asyncio_timeout(seconds=3)
@pytest.mark.parametrize(
    "use_ieee,dev_addr",
    [
        (True,
         t.AddrModeAddress(mode=t.AddrMode.IEEE, address=t.EUI64(range(8)))),
        (False, t.AddrModeAddress(mode=t.AddrMode.NWK, address=t.NWK(0xAABB))),
    ],
)
async def test_request_use_ieee(application, mocker, use_ieee, dev_addr):
    app, znp_server = application
    device = app.add_device(ieee=t.EUI64(range(8)), nwk=0xAABB)

    send_req = mocker.patch.object(app, "_send_request", new=CoroutineMock())

    await app.request(
        device,
        use_ieee=use_ieee,
        profile=None,
        cluster=None,
        src_ep=None,
예제 #7
0
def test_command_param_binding():
    # No params
    c.SysCommands.Ping.Req()

    # Invalid param name
    with pytest.raises(KeyError):
        c.SysCommands.Ping.Rsp(asd=123)

    # Valid param name
    c.SysCommands.Ping.Rsp(Capabilities=t.MTCapabilities.CAP_SYS)

    # Too many params, one valid
    with pytest.raises(KeyError):
        c.SysCommands.Ping.Rsp(foo="asd",
                               Capabilities=t.MTCapabilities.CAP_SYS)

    # Not enough params
    with pytest.raises(KeyError):
        c.SysCommands.Ping.Rsp()

    # Invalid type
    with pytest.raises(ValueError):
        c.UtilCommands.TimeAlive.Rsp(Seconds=b"asd")

    # Coerced numerical type
    a = c.UtilCommands.TimeAlive.Rsp(Seconds=12)
    b = c.UtilCommands.TimeAlive.Rsp(Seconds=t.uint32_t(12))

    assert a == b
    assert a.Seconds == b.Seconds
    assert type(a.Seconds) == type(b.Seconds) == t.uint32_t  # noqa: E721

    # Overflowing integer types
    with pytest.raises(ValueError):
        c.UtilCommands.TimeAlive.Rsp(Seconds=10**20)

    # Integers will not be coerced to enums
    assert t.MTCapabilities.CAP_SYS == 0x0001

    with pytest.raises(ValueError):
        c.SysCommands.Ping.Rsp(Capabilities=0x0001)

    # Parameters can be looked up by name
    ping_rsp = c.SysCommands.Ping.Rsp(Capabilities=t.MTCapabilities.CAP_SYS)
    assert ping_rsp.Capabilities == t.MTCapabilities.CAP_SYS

    # Invalid ones cannot
    with pytest.raises(AttributeError):
        ping_rsp.Oops

    # bytes are converted into t.ShortBytes
    cmd = c.SysCommands.NVWrite.Req(SysId=0x12,
                                    ItemId=0x3456,
                                    SubId=0x7890,
                                    Offset=0x0000,
                                    Value=b"asdfoo")
    assert isinstance(cmd.Value, t.ShortBytes)

    # Lists are converted to typed LVLists
    c.UtilCommands.BindAddEntry.Req(
        DstAddrModeAddr=t.AddrModeAddress(mode=t.AddrMode.NWK, address=0x1234),
        DstEndpoint=0x56,
        ClusterIdList=[0x12, 0x45],
    )

    # Type errors within containers are also caught
    with pytest.raises(ValueError):
        c.UtilCommands.BindAddEntry.Req(
            DstAddrModeAddr=t.AddrModeAddress(mode=t.AddrMode.NWK,
                                              address=0x1234),
            DstEndpoint=0x56,
            ClusterIdList=[0x12,
                           0x457890],  # 0x457890 doesn't fit into a uint8_t
        )