Esempio n. 1
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(
            "Sending Zigbee broadcast with tsn %s under %s request id, data: %s",
            sequence, req_id, binascii.hexlify(data))
        dst_addr_ep = t.DeconzAddressEndpoint()
        dst_addr_ep.address_mode = t.uint8_t(t.ADDRESS_MODE.GROUP.value)
        dst_addr_ep.address = t.uint16_t(broadcast_address)

        with self._pending.new(req_id) as req:
            try:
                await self._api.aps_data_request(req_id, dst_addr_ep, profile,
                                                 cluster, min(1, src_ep), data)
            except zigpy_deconz.exception.CommandError as ex:
                return ex.status, "Couldn't enqueue send data request for broadcast: {}".format(
                    ex)

            r = await asyncio.wait_for(req.result, SEND_CONFIRM_TIMEOUT)

            if r:
                LOGGER.warning(
                    "Error while sending %s req id broadcast: 0x%02x", req_id,
                    r)
                return r, "broadcast send failure"
            return r, "broadcast send success"
Esempio n. 2
0
def test_deconz_addr_ep():
    data = b"\x01\xaa\x55"
    extra = b"the rest of the owl"

    r, rest = t.DeconzAddressEndpoint.deserialize(data + extra)
    assert rest == extra
    assert r.address_mode == t.ADDRESS_MODE.GROUP
    assert r.address == 0x55AA
    assert r.serialize() == data
    a = t.DeconzAddressEndpoint()
    a.address_mode = 1
    a.address = 0x55AA
    assert a.serialize() == data

    data = b"\x02\xaa\x55\xcc"
    r, rest = t.DeconzAddressEndpoint.deserialize(data + extra)
    assert rest == extra
    assert r.address_mode == t.ADDRESS_MODE.NWK
    assert r.address == 0x55AA
    assert r.endpoint == 0xCC
    assert r.serialize() == data
    a = t.DeconzAddressEndpoint()
    a.address_mode = 2
    a.address = 0x55AA
    with pytest.raises(AttributeError):
        a.serialize()
    a.endpoint = 0xCC
    assert a.serialize() == data

    data = b"\x03\x31\x32\x33\x34\x35\x36\x37\x38\xcc"
    r, rest = t.DeconzAddressEndpoint.deserialize(data + extra)
    assert rest == extra
    assert r.address_mode == t.ADDRESS_MODE.IEEE
    assert r.address == [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38]
    assert r.endpoint == 0xCC
    assert r.serialize() == data
    a = t.DeconzAddressEndpoint()
    a.address_mode = 3
    a.address = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38]
    with pytest.raises(AttributeError):
        a.serialize()
    a.endpoint = 0xCC
    assert a.serialize() == data
Esempio n. 3
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(
            "Sending Zigbee multicast with tsn %s under %s request id, data: %s",
            sequence,
            req_id,
            binascii.hexlify(data),
        )
        dst_addr_ep = t.DeconzAddressEndpoint()
        dst_addr_ep.address_mode = t.ADDRESS_MODE.GROUP
        dst_addr_ep.address = group_id

        async with self._limit_concurrency():
            with self._pending.new(req_id) as req:
                try:
                    await self._api.aps_data_request(req_id, dst_addr_ep,
                                                     profile, cluster,
                                                     min(1, src_ep), data)
                except zigpy_deconz.exception.CommandError as ex:
                    return ex.status, f"Couldn't enqueue send data request: {ex!r}"

                r = await asyncio.wait_for(req.result, SEND_CONFIRM_TIMEOUT)
                if r:
                    LOGGER.debug("Error while sending %s req id frame: %s",
                                 req_id, r)
                    return r, f"message send failure: {r}"

            return Status.SUCCESS, "message send success"
Esempio n. 4
0
def _fake_args(arg_type):
    if isinstance(arg_type(), t.DeconzAddressEndpoint):
        addr = t.DeconzAddressEndpoint()
        addr.address_mode = t.ADDRESS_MODE.NWK
        addr.address = t.uint8_t(0)
        addr.endpoint = t.uint8_t(0)
        return addr
    if isinstance(arg_type(), t.EUI64):
        return t.EUI64([0x01] * 8)

    return arg_type()
Esempio n. 5
0
    async def request(
        self,
        device,
        profile,
        cluster,
        src_ep,
        dst_ep,
        sequence,
        data,
        expect_reply=True,
        use_ieee=False,
    ):
        req_id = self.get_sequence()
        LOGGER.debug(
            "Sending Zigbee request with tsn %s under %s request id, data: %s",
            sequence,
            req_id,
            binascii.hexlify(data),
        )
        dst_addr_ep = t.DeconzAddressEndpoint()
        dst_addr_ep.endpoint = t.uint8_t(dst_ep)
        if use_ieee:
            dst_addr_ep.address_mode = t.uint8_t(t.ADDRESS_MODE.IEEE)
            dst_addr_ep.address = device.ieee
        else:
            dst_addr_ep.address_mode = t.uint8_t(t.ADDRESS_MODE.NWK)
            dst_addr_ep.address = device.nwk

        tx_options = t.DeconzTransmitOptions.USE_NWK_KEY_SECURITY

        async with self._limit_concurrency():
            with self._pending.new(req_id) as req:
                try:
                    await self._api.aps_data_request(
                        req_id,
                        dst_addr_ep,
                        profile,
                        cluster,
                        min(1, src_ep),
                        data,
                        tx_options=tx_options,
                    )
                except zigpy_deconz.exception.CommandError as ex:
                    return ex.status, f"Couldn't enqueue send data request: {ex!r}"

                r = await asyncio.wait_for(req.result, SEND_CONFIRM_TIMEOUT)

                if r:
                    LOGGER.debug("Error while sending %s req id frame: %s",
                                 req_id, r)
                    return r, "message send failure"

                return r, "message send success"
Esempio n. 6
0
def _fake_args(arg_type):
    if issubclass(arg_type, enum.Enum):
        return list(arg_type)[0]  # Pick the first enum value
    elif issubclass(arg_type, t.DeconzAddressEndpoint):
        addr = t.DeconzAddressEndpoint()
        addr.address_mode = t.ADDRESS_MODE.NWK
        addr.address = t.uint8_t(0)
        addr.endpoint = t.uint8_t(0)
        return addr
    elif issubclass(arg_type, t.EUI64):
        return t.EUI64([0x01] * 8)

    return arg_type()
Esempio n. 7
0
def test_api_frame(api):
    addr = t.DeconzAddressEndpoint()
    addr.address_mode = t.ADDRESS_MODE.NWK
    addr.address = t.uint8_t(0)
    addr.endpoint = t.uint8_t(0)
    for cmd, schema in deconz_api.TX_COMMANDS.items():
        if schema:
            args = [
                addr if isinstance(a(), t.DeconzAddressEndpoint) else a()
                for a in schema
            ]
            api._api_frame(cmd, *args)
        else:
            api._api_frame(cmd)