Ejemplo n.º 1
0
def test_join(app):
    payload = {
        "nwkaddr": 27441,
        "extaddr": "0x07a3c302008d1500",
        "parentaddr": 0
    }
    obj = ZpiObject(2, 5, "tcDeviceInd", 202, payload, [])
    app.handle_znp(obj)

    print(app.devices)

    payload = {
        "groupid": 0,
        "clusterid": 6,
        "srcaddr": 27441,
        "srcendpoint": 1,
        "dstendpoint": 1,
        "wasbroadcast": 0,
        "linkquality": 136,
        "securityuse": 0,
        "timestamp": 15458350,
        "transseqnumber": 0,
        "len": 7,
        "data": bytearray(b"\x18\x0c\n\x00\x00\x10\x00"),
    }
    obj = ZpiObject(2, 4, "incomingMsg", 129, payload, [])
    app.handle_znp(obj)
Ejemplo n.º 2
0
def test_join(app):
    payload = {'nwkaddr': 27441, 'extaddr': '0x07a3c302008d1500', 'parentaddr': 0}
    obj = ZpiObject(2, 5, 'tcDeviceInd', 202, payload, [])
    app.handle_znp(obj)

    print(app.devices)

    payload = {'groupid': 0, 'clusterid': 6, 'srcaddr': 27441, 'srcendpoint': 1, 'dstendpoint': 1, 'wasbroadcast': 0,
               'linkquality': 136, 'securityuse': 0, 'timestamp': 15458350, 'transseqnumber': 0, 'len': 7,
               'data': bytearray(b'\x18\x0c\n\x00\x00\x10\x00')}
    obj = ZpiObject(2, 4, 'incomingMsg', 129, payload, [])
    app.handle_znp(obj)
Ejemplo n.º 3
0
def test_from_cluster_id_ZCL():
    profile = 260
    obj = ZpiObject.from_cluster(t.NWK(53322), profile, 0, 1, 1, 1, b'\x00\x0b\x00\x04\x00\x05\x00', 123)

    assert "SREQ AF dataRequest tsn: 1 {'dstaddr': 53322, 'destendpoint': 1, 'srcendpoint': 1, " \
           "'clusterid': 0, 'transid': 123, 'options': 0, 'radius': 30, 'len': 7, " \
           "'data': b'\\x00\\x0b\\x00\\x04\\x00\\x05\\x00'}" == str(obj)
Ejemplo n.º 4
0
    def data_received(self, frame):
        try:
            obj = ZpiObject.from_unpi_frame(frame)
        except Exception as e:
            LOGGER.error("Error while parsing frame: %s", frame)
            raise e

        for waiter_id in list(self._waiters):
            waiter = self._waiters.get(waiter_id)
            if waiter.match(obj):
                self._waiters.pop(waiter_id)
                waiter.set_result(obj)
                if waiter.sequence:
                    obj.sequence = waiter.sequence
                    break

        LOGGER.debug("<-- %s", obj)

        if self._app is not None:
            self._app.handle_znp(obj)

        try:
            getattr(self, "_handle_%s" % (obj.command, ))(obj)
        except AttributeError:
            pass
Ejemplo n.º 5
0
def test_data_received(api, monkeypatch):
    monkeypatch.setattr(
        t,
        "deserialize",
        mock.MagicMock(return_value=(mock.sentinel.deserialize_data, b"")),
    )
    my_handler = mock.MagicMock()

    data = UnpiFrame(3, 1, 2,
                     b"\x02\x00\x02\x06\x03\x90\x154\x01\x02\x01\x00\x00\x00")
    setattr(api, "_handle_version", my_handler)
    api._awaiting[0] = mock.MagicMock()
    api.data_received(data)
    # assert t.deserialize.call_count == 1
    # assert t.deserialize.call_args[0][0] == payload
    assert my_handler.call_count == 1
    assert str(my_handler.call_args[0][0]) == str(
        ZpiObject(
            3, 1, "version", 2, {
                'transportrev': 2,
                'product': 0,
                'majorrel': 2,
                'minorrel': 6,
                'maintrel': 3,
                'revision': 20190608
            }, []))
Ejemplo n.º 6
0
def test_ieee_addr():
    # 3 - 7 - 0 - 18 - [bytearray(b'\x00\x0c%\xed\x18\x00K\x12\x00\x00\x00\x07\t\x02J\xd0]\x97')] - 172
    frame = uart.UnpiFrame(3, 7, 0, b'\x00\x0c%\xed\x18\x00K\x12\x00\x00\x00\x07\t\x02J\xd0]\x97')
    obj = ZpiObject.from_unpi_frame(frame)

    out = obj.to_unpi_frame()
    assert out.data == b'\x00\x00\x12K\x00\x18\xed%\x0c\x00\x00\x07\t\x02J\xd0]\x97'
Ejemplo n.º 7
0
def test_from_unpi_frame3():
    payload = {
        "groupid":0,
        "clusterid":0,
        "srcaddr":44052,
        "srcendpoint":1,
        "dstendpoint":1,
        "wasbroadcast":0,
        "linkquality":78,
        "securityuse":0,
        "timestamp":2206697,
        "transseqnumber":0,
        "len":55,
        "data":bytes([24,2,1,5,0,0,66,23,84,82,65,68,70,82,73,32,119,105,114,101,108,101,115,115,32,100,105,109,109,101,114,4,0,0,66,14,73,75,69,65,32,111,102,32,83,119,101,100,101,110,7,0,0,48,3])
    }
    obj = ZpiObject.from_command(
        t.CommandType.AREQ,
        t.Subsystem.AF,
        'incomingMsg',
        payload
    )

    assert "AREQ AF incomingMsg tsn: None {'groupid': 0, 'clusterid': 0, 'srcaddr': 44052, " \
           "'srcendpoint': 1, 'dstendpoint': 1, 'wasbroadcast': 0, 'linkquality': 78, " \
           "'securityuse': 0, 'timestamp': 2206697, 'transseqnumber': 0, 'len': 55, " \
           "'data': b'\\x18\\x02\\x01\\x05\\x00\\x00B\\x17TRADFRI wireless dimmer\\x04\\x00\\x00B\\x0eIKEA of Sweden\\x07\\x00\\x000\\x03'}" == str(obj)
Ejemplo n.º 8
0
async def test_get_node_descriptor(app: application.ControllerApplication):
    await device_annce(app)
    device = app.get_device(nwk=53322)

    fut = asyncio.Future()
    fut.set_result([0, "message send success"])
    app._api.request_raw = mock.MagicMock(return_value=fut)

    payload = {
        "srcaddr": 53322,
        "status": 0,
        "nwkaddr": 0,
        "logicaltype_cmplxdescavai_userdescavai": 0,
        "apsflags_freqband": 0,
        "maccapflags": 0,
        "manufacturercode": 1234,
        "maxbuffersize": 0,
        "maxintransfersize": 0,
        "servermask": 0,
        "maxouttransfersize": 0,
        "descriptorcap": 0,
    }
    obj = ZpiObject.from_command(5, "nodeDescRsp", payload)
    frame = obj.to_unpi_frame()

    async def nested():
        await asyncio.sleep(0)
        app._api.data_received(frame)

    await asyncio.wait([device.get_node_descriptor(), nested()], timeout=0.2)

    assert isinstance(device.node_desc, zdo_t.NodeDescriptor)
    assert 1234 == device.node_desc.manufacturer_code
Ejemplo n.º 9
0
def test_ieee_addr():
    frame = uart.UnpiFrame(
        3, 7, 0, b"\x00\x0c%\xed\x18\x00K\x12\x00\x00\x00\x07\t\x02J\xd0]\x97")
    obj = ZpiObject.from_unpi_frame(frame)

    out = obj.to_unpi_frame()
    assert out.data == b"\x00\x00\x12K\x00\x18\xed%\x0c\x00\x00\x07\t\x02J\xd0]\x97"
Ejemplo n.º 10
0
def test_mgmt_lqi_rsp():
    frame = uart.UnpiFrame(
        2,
        5,
        177,
        b"\x00\x00\x00\x14\x00\x03\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\x1d$&\xfe\xffW\xb4\x14\xef>\x15\x02\x01\x00\xdd"
        b"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\x9atk\x03\x00\x8d\x15\x00}0\x12\x02\x01`\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\x8d(,"
        b"\x03\x00\x8d\x15\x00}\xcc\x12\x02\x017",
        72,
        34,
    )
    obj = ZpiObject.from_unpi_frame(frame)
    assert (
        "AREQ ZDO mgmtLqiRsp tsn: None {"
        "'srcaddr': 0x0000, "
        "'status': 0, "
        "'neighbortableentries': 20, "
        "'startindex': 0, "
        "'neighborlqilistcount': 3, "
        "'neighborlqilist': ["
        "{'extPanId': dd:dd:dd:dd:dd:dd:dd:dd, 'extAddr': 14:b4:57:ff:fe:26:24:1d, 'nwkAddr': 0x3EEF, "
        "'deviceType': 1, 'rxOnWhenIdle': 1, 'relationship': 1, 'permitJoin': 2, 'depth': 1, 'lqi': 0}, "
        "{'extPanId': dd:dd:dd:dd:dd:dd:dd:dd, 'extAddr': 00:15:8d:00:03:6b:74:9a, 'nwkAddr': 0x307D, "
        "'deviceType': 2, 'rxOnWhenIdle': 0, 'relationship': 1, 'permitJoin': 2, 'depth': 1, 'lqi': 96}, "
        "{'extPanId': dd:dd:dd:dd:dd:dd:dd:dd, 'extAddr': 00:15:8d:00:03:2c:28:8d, 'nwkAddr': 0xCC7D, "
        "'deviceType': 2, 'rxOnWhenIdle': 0, 'relationship': 1, 'permitJoin': 2, 'depth': 1, 'lqi': 55}"
        "]}" == str(obj)
    )
Ejemplo n.º 11
0
def test_bind_req():
    '''
    zigpy_cc.zigbee.application DEBUG request (
        0xbd8b, 0, <ZDOCmd.Bind_req: 0x0021>, 0, 0, 1,
        b"\x01<x'\xfe\xffW\x0b\x00\x01\x08\x00\x03\x0c%\xed\x18\x00K\x12\x00\x01", True, False)
    zigpy_cc.api DEBUG waiting for 1 bindReq
    zigpy_cc.api DEBUG --> SREQ ZDO bindReq tsn: 1 {
        'dstaddr': 0xbd8b, 'srcaddr': 00:0b:57:ff:fe:27:78:3c, 'srcendpoint': 1, 'clusterid': 8, 'dstaddrmode': 3, 'dstaddress': 00:12:4b:00:18:ed:25:0c, 'dstendpoint': 1}
    zigpy_cc.uart DEBUG Send:
        b"\xfe\x17%!\x8b\xbd<x'\xfe\xffW\x0b\x00\x01\x08\x00\x03\x0c%\xed\x18\x00K\x12\x00\x01\x95"

    '''

    data = b"\x02<x'\xfe\xffW\x0b\x00\x01\x08\x00\x03\x0c%\xed\x18\x00K\x12\x00\x01"

    obj = ZpiObject.from_cluster(
        NWK(0x6292), 0, 0x0021, 0, 0, 2, data, 123
    )

    assert (
            "SREQ ZDO bindReq tsn: 2 {"
            "'dstaddr': 0x6292, "
            "'srcaddr': 00:0b:57:ff:fe:27:78:3c, "
            "'srcendpoint': 1, "
            "'clusterid': 8, "
            "'dstaddrmode': 3, "
            "'dstaddress': 00:12:4b:00:18:ed:25:0c, "
            "'dstendpoint': 1}" == str(obj)
    )
    assert (
            bytes(
                [254, 23, 37, 33, 146, 98, 60, 120, 39, 254, 255, 87, 11, 0, 1, 8, 0, 3,
                 12, 37, 237, 24, 0, 75, 18, 0, 1, 83])
            == obj.to_unpi_frame().to_buffer()
    )
Ejemplo n.º 12
0
def test_bind_req_serialize():
    payload = {"dstaddr": NWK(25234),
               "srcaddr": EUI64(reversed(b'\x00\x0b\x57\xff\xfe\x27\x78\x3c')),
               "srcendpoint": 1,
               "clusterid": 8,
               "dstaddrmode": 3,
               "dstaddress": EUI64(reversed(b'\x00\x12\x4b\x00\x18\xed\x25\x0c')),
               "dstendpoint": 1}
    obj = ZpiObject.from_command(t.Subsystem.ZDO, 'bindReq', payload)
    assert (
            "SREQ ZDO bindReq tsn: None {"
            "'dstaddr': 0x6292, "
            "'srcaddr': 00:0b:57:ff:fe:27:78:3c, "
            "'srcendpoint': 1, "
            "'clusterid': 8, "
            "'dstaddrmode': 3, "
            "'dstaddress': 00:12:4b:00:18:ed:25:0c, "
            "'dstendpoint': 1}" == str(obj)
    )
    assert (
            bytes(
                [254, 23, 37, 33, 146, 98, 60, 120, 39, 254, 255, 87, 11, 0, 1, 8, 0, 3,
                 12, 37, 237, 24, 0, 75, 18, 0, 1, 83])
            == obj.to_unpi_frame().to_buffer()
    )
Ejemplo n.º 13
0
async def test_get_node_descriptor(app: application.ControllerApplication):
    await device_annce(app)
    device = app.get_device(nwk=53322)

    fut = asyncio.Future()
    fut.set_result([0, 'message send success'])
    app._api.request_raw = mock.MagicMock(return_value=fut)

    payload = {'srcaddr': 53322, 'status': 0, 'nwkaddr': 0, 'logicaltype_cmplxdescavai_userdescavai': 0,
               'apsflags_freqband': 0, 'maccapflags': 0, 'manufacturercode': 1234, 'maxbuffersize': 0,
               'maxintransfersize': 0, 'servermask': 0, 'maxouttransfersize': 0, 'descriptorcap': 0}
    obj = ZpiObject.from_command(2, 5, 'nodeDescRsp', payload)
    frame = obj.to_unpi_frame()

    async def nested():
        await asyncio.sleep(0)
        app._api.data_received(frame)

    await asyncio.wait([
        device.get_node_descriptor(),
        nested(),
    ], timeout=0.2)

    assert isinstance(device.node_desc, zdo_t.NodeDescriptor)
    assert device.node_desc.manufacturer_code == 1234
Ejemplo n.º 14
0
def test_from_cluster_id():
    profile = 0
    obj = ZpiObject.from_cluster(NWK(53322), profile, ZDOCmd.Node_Desc_req, 0,
                                 0, 0, b"\x03\x4a\xd0", 32)

    assert (
        "SREQ ZDO nodeDescReq tsn: 0 {'dstaddr': 0xd04a, 'nwkaddrofinterest': 0xd04a}"
        == str(obj))
Ejemplo n.º 15
0
 async def request(self,
                   subsystem,
                   command,
                   payload,
                   waiter_id=None,
                   expected_status=None):
     obj = ZpiObject.from_command(subsystem, command, payload)
     return await self.request_raw(obj, waiter_id, expected_status)
Ejemplo n.º 16
0
async def device_annce(app: application.ControllerApplication):
    # payload = {'nwkaddr': 27441, 'extaddr': '0x07a3c302008d1500', 'parentaddr': 0}
    # obj = ZpiObject(2, 5, 'tcDeviceInd', 202, payload, [])

    payload = {'srcaddr': 53322, 'nwkaddr': 53322, 'ieeeaddr': 0x41e54b02008d1500.to_bytes(8, 'little'),
               'capabilities': 132}
    obj = ZpiObject(2, 5, 'endDeviceAnnceInd', 193, payload, [])

    app.handle_znp(obj)
Ejemplo n.º 17
0
    async def broadcast(
        self,
        profile,
        cluster,
        src_ep,
        dst_ep,
        grpid,
        radius,
        sequence,
        data,
        broadcast_address=zigpy.types.BroadcastAddress.RX_ON_WHEN_IDLE,
    ):
        LOGGER.debug(
            "broadcast %s",
            (
                profile,
                cluster,
                src_ep,
                dst_ep,
                grpid,
                radius,
                sequence,
                data,
                broadcast_address,
            ),
        )
        try:
            obj = ZpiObject.from_cluster(
                broadcast_address,
                profile,
                cluster,
                src_ep,
                dst_ep,
                sequence,
                data,
                radius=radius,
                addr_mode=AddressMode.ADDR_16BIT,
            )

            async with self._semaphore:
                await self._api.request_raw(obj)
                """
                As a broadcast command is not confirmed and thus immediately returns
                (contrary to network address requests) we will give the
                command some time to 'settle' in the network.
                """
                await asyncio.sleep(0.2)

        except CommandError as ex:
            return (
                ex.status,
                "Couldn't enqueue send data request for broadcast: {}".format(
                    ex),
            )

        return 0, "broadcast send success"
Ejemplo n.º 18
0
    async def _request_raw(self,
                           obj: ZpiObject,
                           waiter_id=None,
                           expected_status=None):
        if expected_status is None:
            expected_status = [0]

        LOGGER.debug("--> %s", obj)
        frame = obj.to_unpi_frame()

        if obj.command_type == CommandType.SREQ:
            timeout = (20000 if obj.command == "bdbStartCommissioning"
                       or obj.command == "startupFromApp" else Timeouts.SREQ)
            waiter = self.wait_for(CommandType.SRSP, obj.subsystem,
                                   obj.command, {}, timeout)
            self._uart.send(frame)
            result = await waiter.wait()
            if (result and "status" in result.payload
                    and result.payload["status"] not in expected_status):
                if waiter_id is not None:
                    self._waiters.pop(waiter_id).set_result(result)

                raise CommandError(
                    result.payload["status"],
                    "SREQ '{}' failed with status '{}' (expected '{}')".format(
                        obj.command, result.payload["status"],
                        expected_status),
                )
            else:
                return result
        elif obj.command_type == CommandType.AREQ and obj.is_reset_command():
            waiter = self.wait_for(CommandType.AREQ, Subsystem.SYS, "resetInd",
                                   {}, Timeouts.reset)
            # TODO clear queue, requests waiting for lock
            self._uart.send(frame)
            return await waiter.wait()
        else:
            if obj.command_type == CommandType.AREQ:
                self._uart.send(frame)
                return None
            else:
                LOGGER.warning("Unknown type '%s'", obj.command_type)
                raise Exception("Unknown type '{}'".format(obj.command_type))
Ejemplo n.º 19
0
def test_from_unpi_frame2():
    frame = uart.UnpiFrame(
        2, 4, 129,
        b'\x00\x00\x01\x00\xbbm\x01\x01\x00s\x00YC3\x00\x00\t\x18\x01\x01\x04\x00\x86\x05\x00\x86\xbbm\x1d'
    )

    obj = ZpiObject.from_unpi_frame(frame)

    assert "AREQ AF incomingMsg tsn: None {'groupid': 0, 'clusterid': 1, 'srcaddr': 0x6dbb, " \
           "'srcendpoint': 1, 'dstendpoint': 1, 'wasbroadcast': 0, 'linkquality': 115, " \
           "'securityuse': 0, 'timestamp': 3359577, 'transseqnumber': 0, 'len': 9, " \
           "'data': b'\\x18\\x01\\x01\\x04\\x00\\x86\\x05\\x00\\x86'}" == str(obj)
Ejemplo n.º 20
0
async def device_annce(app: application.ControllerApplication):
    # payload = {'nwkaddr': 27441, 'extaddr': '0x07a3c302008d1500', 'parentaddr': 0}
    # obj = ZpiObject(2, 5, 'tcDeviceInd', 202, payload, [])

    payload = {
        "srcaddr": 53322,
        "nwkaddr": 53322,
        "ieeeaddr": 0x41E54B02008D1500.to_bytes(8, "little"),
        "capabilities": 132,
    }
    obj = ZpiObject(2, 5, "endDeviceAnnceInd", 193, payload, [])

    app.handle_znp(obj)
Ejemplo n.º 21
0
    async def mrequest(self,
                       group_id,
                       profile,
                       cluster,
                       src_ep,
                       sequence,
                       data,
                       *,
                       hops=0,
                       non_member_radius=3):
        """Submit and send data out as a multicast transmission.

        :param group_id: destination multicast address
        :param profile: Zigbee Profile ID to use for outgoing message
        :param cluster: cluster id where the message is being sent
        :param src_ep: source endpoint id
        :param sequence: transaction sequence number of the message
        :param data: Zigbee message payload
        :param hops: the message will be delivered to all nodes within this number of
                     hops of the sender. A value of zero is converted to MAX_HOPS
        :param non_member_radius: the number of hops that the message will be forwarded
                                  by devices that are not members of the group. A value
                                  of 7 or greater is treated as infinite
        :returns: return a tuple of a status and an error_message. Original requestor
                  has more context to provide a more meaningful error message
        """
        req_id = self.get_sequence()
        LOGGER.debug(
            "multicast %s",
            (
                group_id,
                profile,
                cluster,
                src_ep,
                sequence,
                data,
                hops,
                non_member_radius,
            ),
        )
        try:
            obj = ZpiObject.from_cluster(group_id, profile, cluster, src_ep,
                                         src_ep, sequence, data, req_id)

            await self._api.request_raw(obj)

        except CommandError as ex:
            return ex.status, "Couldn't enqueue send data multicast: {}".format(
                ex)

        return 0, "message send success"
Ejemplo n.º 22
0
    async def broadcast(
        self,
        profile,
        cluster,
        src_ep,
        dst_ep,
        grpid,
        radius,
        sequence,
        data,
        broadcast_address=zigpy.types.BroadcastAddress.RX_ON_WHEN_IDLE,
    ):
        req_id = self.get_sequence()
        LOGGER.debug(
            "broadcast %s",
            (
                profile,
                cluster,
                src_ep,
                dst_ep,
                grpid,
                radius,
                sequence,
                data,
                broadcast_address,
            ),
        )
        try:
            obj = ZpiObject.from_cluster(
                broadcast_address,
                profile,
                cluster,
                src_ep,
                dst_ep,
                sequence,
                data,
                req_id,
                radius=radius,
            )

            await self._api.request_raw(obj)

        except CommandError as ex:
            return (
                ex.status,
                "Couldn't enqueue send data request for broadcast: {}".format(
                    ex),
            )

        return 0, "broadcast send success"
Ejemplo n.º 23
0
def test_from_unpi_frame():
    frame = uart.UnpiFrame(3, 1, 2, b"\x02\x00\x02\x06\x03\x90\x154\x01")
    extra = {
        "maintrel": 3,
        "majorrel": 2,
        "minorrel": 6,
        "product": 0,
        "revision": 20190608,
        "transportrev": 2,
    }

    obj = ZpiObject.from_unpi_frame(frame)
    assert obj.command == "version"
    assert obj.payload == extra

    assert str(obj.to_unpi_frame()) == str(frame)
Ejemplo n.º 24
0
def test_mgmt_nwk_update_notify():
    frame = uart.UnpiFrame(
        2,
        5,
        184,
        b"\xe9\xc0\x00\x00\xf8\xff\x07\x14\x00\x0f\x00\x10\xd6\xac"
        b"\xcc\xb0\xb5\xa2\xb2\xa5\xb3\xa5\xa2\xa9\xa1\xa1\xa5\xae",
        28,
        211,
    )
    obj = ZpiObject.from_unpi_frame(frame)
    assert (
        "AREQ ZDO mgmtNwkUpdateNotify tsn: None {'srcaddr': 0xc0e9, 'status': 0, 'scanchannels': 134215680, "
        "'totaltransmissions': 20, 'transmissionfailures': 15, 'channelcount': 16, "
        "'energyvalues': [214, 172, 204, 176, 181, 162, 178, 165, 179, 165, 162, 169, 161, 161, 165, 174]"
        "}" == str(obj))
Ejemplo n.º 25
0
def test_from_unpi_frame():
    frame = uart.UnpiFrame(3, 1, 2, b"\x02\x00\x02\x06\x03\x90\x154\x01")
    extra = {
        'maintrel': 3,
        'majorrel': 2,
        'minorrel': 6,
        'product': 0,
        'revision': 20190608,
        'transportrev': 2,
    }

    obj = ZpiObject.from_unpi_frame(frame)
    assert obj.command == 'version'
    assert obj.payload == extra

    assert str(obj.to_unpi_frame()) == str(frame)
Ejemplo n.º 26
0
    async def request(
        self,
        device,
        profile,
        cluster,
        src_ep,
        dst_ep,
        sequence,
        data,
        expect_reply=True,
        use_ieee=False,
    ):
        LOGGER.debug(
            "request %s",
            (
                device.nwk,
                profile,
                cluster,
                src_ep,
                dst_ep,
                sequence,
                data,
                expect_reply,
                use_ieee,
            ),
        )

        try:
            obj = ZpiObject.from_cluster(device.nwk, profile, cluster, src_ep,
                                         dst_ep, sequence, data)
            waiter_id = None
            if expect_reply:
                waiter = self._api.create_response_waiter(obj, sequence)
                if waiter:
                    waiter_id = waiter.id

            async with self._semaphore:
                await self._api.request_raw(obj, waiter_id)

        except CommandError as ex:
            return ex.status, "Couldn't enqueue send data request: {}".format(
                ex)

        return 0, "message send success"
Ejemplo n.º 27
0
    def handle_znp(self, obj: ZpiObject):
        if obj.type != t.CommandType.AREQ:
            return

        # if obj.subsystem == t.Subsystem.ZDO and obj.command == 'tcDeviceInd':
        #     nwk = obj.payload['nwkaddr']
        #     rest = obj.payload['extaddr'][2:].encode("ascii")
        #     ieee, _ = zigpy.types.EUI64.deserialize(rest)
        #     LOGGER.info("New device joined: 0x%04x, %s", nwk, ieee)
        #     self.handle_join(nwk, ieee, obj.payload['parentaddr'])

        frame = obj.to_unpi_frame()

        nwk = obj.payload["srcaddr"] if "srcaddr" in obj.payload else None
        ieee = obj.payload["ieeeaddr"] if "ieeeaddr" in obj.payload else None
        profile_id = zha.PROFILE_ID
        src_ep = 0
        dst_ep = 0
        lqi = 0
        rssi = 0

        if obj.subsystem == t.Subsystem.ZDO and obj.command == "endDeviceAnnceInd":
            nwk = obj.payload["nwkaddr"]
            LOGGER.info("New device joined: 0x%04x, %s", nwk, ieee)
            self.handle_join(nwk, ieee, 0)
            # TODO TEST
            obj.sequence = 0

        # TODO bindRsp

        if obj.command in IGNORED:
            LOGGER.debug("message ignored: %s", obj.command)
            return

        if obj.subsystem == t.Subsystem.ZDO and obj.command == "permitJoinInd":
            # if obj.payload["duration"] == 0:
            #     loop = asyncio.get_event_loop()
            #     loop.create_task(self.permit_ncp())
            return

        if obj.subsystem == t.Subsystem.ZDO and obj.command in REQUESTS:
            if obj.sequence is None:
                LOGGER.warning("missing tsn from %s, maybe not a reply",
                               obj.command)
                return
            LOGGER.info("REPLY for %d %s", obj.sequence, obj.command)
            cluster_id, prefix_length = REQUESTS[obj.command]
            tsn = bytes([obj.sequence])
            data = tsn + frame.data[prefix_length:]

        elif obj.subsystem == t.Subsystem.AF and (obj.command == "incomingMsg"
                                                  or obj.command
                                                  == "incomingMsgExt"):
            # ZCL commands
            cluster_id = obj.payload["clusterid"]
            src_ep = obj.payload["srcendpoint"]
            dst_ep = obj.payload["dstendpoint"]
            data = obj.payload["data"]
            lqi = obj.payload["linkquality"]

        else:
            LOGGER.warning("Unhandled message: %s %s",
                           t.Subsystem(obj.subsystem), obj.command)
            return

        try:
            if ieee:
                device = self.get_device(ieee=ieee)
            else:
                device = self.get_device(nwk=nwk)
        except KeyError:
            LOGGER.warning("Received frame from unknown device: %s",
                           ieee if ieee else nwk)
            return

        device.radio_details(lqi, rssi)
        # if obj.subsystem == t.Subsystem.ZDO:
        #     pass
        LOGGER.info("handle_message %s", obj.command)
        self.handle_message(device, profile_id, cluster_id, src_ep, dst_ep,
                            data)
Ejemplo n.º 28
0
    async def mrequest(self,
                       group_id,
                       profile,
                       cluster,
                       src_ep,
                       sequence,
                       data,
                       *,
                       hops=0,
                       non_member_radius=3):
        """Submit and send data out as a multicast transmission.

        :param group_id: destination multicast address
        :param profile: Zigbee Profile ID to use for outgoing message
        :param cluster: cluster id where the message is being sent
        :param src_ep: source endpoint id
        :param sequence: transaction sequence number of the message
        :param data: Zigbee message payload
        :param hops: the message will be delivered to all nodes within this number of
                     hops of the sender. A value of zero is converted to MAX_HOPS
        :param non_member_radius: the number of hops that the message will be forwarded
                                  by devices that are not members of the group. A value
                                  of 7 or greater is treated as infinite
        :returns: return a tuple of a status and an error_message. Original requestor
                  has more context to provide a more meaningful error message
        """
        LOGGER.debug(
            "multicast %s",
            (
                group_id,
                profile,
                cluster,
                src_ep,
                sequence,
                data,
                hops,
                non_member_radius,
            ),
        )
        try:
            obj = ZpiObject.from_cluster(
                group_id,
                profile,
                cluster,
                src_ep or 1,
                0xFF,
                sequence,
                data,
                addr_mode=AddressMode.ADDR_GROUP,
            )
            waiter_id = None
            waiter = self._api.create_response_waiter(obj, sequence)
            if waiter:
                waiter_id = waiter.id

            async with self._semaphore:
                await self._api.request_raw(obj, waiter_id)
                """
                As a group command is not confirmed and thus immediately returns
                (contrary to network address requests) we will give the
                command some time to 'settle' in the network.
                """
                await asyncio.sleep(0.2)

        except CommandError as ex:
            return ex.status, "Couldn't enqueue send data multicast: {}".format(
                ex)

        return 0, "message send success"
Ejemplo n.º 29
0
    def handle_znp(self, obj: ZpiObject):
        if obj.type != t.CommandType.AREQ:
            return

        # if obj.subsystem == t.Subsystem.ZDO and obj.command == 'tcDeviceInd':
        #     nwk = obj.payload['nwkaddr']
        #     rest = obj.payload['extaddr'][2:].encode("ascii")
        #     ieee, _ = zigpy.types.EUI64.deserialize(rest)
        #     LOGGER.info("New device joined: 0x%04x, %s", nwk, ieee)
        #     self.handle_join(nwk, ieee, obj.payload['parentaddr'])

        frame = obj.to_unpi_frame()

        nwk = obj.payload['srcaddr'] if 'srcaddr' in obj.payload else None
        ieee = obj.payload['ieeeaddr'] if 'ieeeaddr' in obj.payload else None
        profile_id = zha.PROFILE_ID
        src_ep = 0
        dst_ep = 0
        lqi = 0
        rssi = 0

        if obj.subsystem == t.Subsystem.ZDO and obj.command == 'endDeviceAnnceInd':
            nwk = obj.payload['nwkaddr']
            LOGGER.info("New device joined: 0x%04x, %s", nwk, ieee)
            self.handle_join(nwk, ieee, 0)
            # TODO TEST
            obj.sequence = 0

        if obj.subsystem == t.Subsystem.ZDO and obj.command in REQUESTS:
            if obj.sequence is None:
                LOGGER.warning("missing tsn from %s, maybe not a reply", obj.command)
                return
            cluster_id, prefix_length = REQUESTS[obj.command]
            LOGGER.info("REPLY for %d %s", obj.sequence, obj.command)
            tsn = bytes([obj.sequence])
            data = tsn + frame.data[prefix_length:]

        elif obj.subsystem == t.Subsystem.AF and (obj.command == 'incomingMsg' or obj.command == 'incomingMsgExt'):
            # ZCL commands
            cluster_id = obj.payload['clusterid']
            src_ep = obj.payload['srcendpoint']
            dst_ep = obj.payload['dstendpoint']
            data = obj.payload['data']
            lqi = obj.payload['linkquality']

        elif obj.command == 'stateChangeInd':
            LOGGER.info("State changed to: %s", obj.payload['state'])
            return

        else:
            LOGGER.warning("Unhandled message: %s %s", obj.subsystem, obj.command)
            return

        try:
            if ieee:
                device = self.get_device(ieee=ieee)
            else:
                device = self.get_device(nwk=nwk)
        except KeyError:
            LOGGER.debug("Received frame from unknown device: %s", ieee if ieee else nwk)
            return

        device.radio_details(lqi, rssi)
        if obj.subsystem == t.Subsystem.ZDO:
            pass
        LOGGER.info('handle_message %s', obj.command)
        self.handle_message(device, profile_id, cluster_id, src_ep, dst_ep, data)
Ejemplo n.º 30
0
    def handle_znp(self, obj: ZpiObject):
        if obj.command_type != t.CommandType.AREQ:
            return

        frame = obj.to_unpi_frame()

        nwk = obj.payload["srcaddr"] if "srcaddr" in obj.payload else None
        ieee = obj.payload["ieeeaddr"] if "ieeeaddr" in obj.payload else None
        profile_id = zha.PROFILE_ID
        src_ep = 0
        dst_ep = 0
        lqi = 0
        rssi = 0

        if obj.subsystem == t.Subsystem.ZDO and obj.command == "endDeviceAnnceInd":
            nwk = obj.payload["nwkaddr"]
            LOGGER.info("New device joined: 0x%04x, %s", nwk, ieee)
            self.handle_join(nwk, ieee, 0)
            obj.sequence = 0

        if obj.command in IGNORED:
            return

        if obj.subsystem == t.Subsystem.ZDO and obj.command == "mgmtPermitJoinRsp":
            self.set_led(LedMode.On)

        if obj.subsystem == t.Subsystem.ZDO and obj.command == "permitJoinInd":
            self.set_led(LedMode.Off if obj.payload["duration"] ==
                         0 else LedMode.On)
            return

        if obj.subsystem == t.Subsystem.ZDO and obj.command in REQUESTS:
            if obj.sequence is None:
                return
            LOGGER.debug("REPLY for %d %s", obj.sequence, obj.command)
            cluster_id, prefix_length = REQUESTS[obj.command]
            tsn = bytes([obj.sequence])
            data = tsn + frame.data[prefix_length:]

        elif obj.subsystem == t.Subsystem.AF and (obj.command == "incomingMsg"
                                                  or obj.command
                                                  == "incomingMsgExt"):
            # ZCL commands
            cluster_id = obj.payload["clusterid"]
            src_ep = obj.payload["srcendpoint"]
            dst_ep = obj.payload["dstendpoint"]
            data = obj.payload["data"]
            lqi = obj.payload["linkquality"]

        else:
            LOGGER.warning(
                "Unhandled message: %s %s %s",
                t.CommandType(obj.command_type),
                t.Subsystem(obj.subsystem),
                obj.command,
            )
            return

        try:
            if ieee:
                device = self.get_device(ieee=ieee)
            else:
                device = self.get_device(nwk=nwk)
        except KeyError:
            LOGGER.warning("Received frame from unknown device: %s",
                           ieee if ieee else nwk)
            return

        device.radio_details(lqi, rssi)

        LOGGER.info("handle_message %s", obj.command)
        self.handle_message(device, profile_id, cluster_id, src_ep, dst_ep,
                            data)