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"
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
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"
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()
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"
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()
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)