4747STARTUP_TIMEOUT = 5
4848ZDO_REQUEST_TIMEOUT = 15
4949DATA_CONFIRM_TIMEOUT = 8
50+ IEEE_ADDR_DISCOVERY_TIMEOUT = 5
5051DEVICE_JOIN_MAX_DELAY = 5
5152WATCHDOG_PERIOD = 30
5253BROADCAST_SEND_WAIT_DURATION = 3
@@ -670,6 +671,12 @@ def _bind_callbacks(self) -> None:
670671 self .on_intentionally_unhandled_message ,
671672 )
672673
674+ # These are responses to a broadcast but we ignore all but the first
675+ self ._znp .callback_for_response (
676+ c .ZDO .IEEEAddrRsp .Callback (partial = True ),
677+ self .on_intentionally_unhandled_message ,
678+ )
679+
673680 def on_intentionally_unhandled_message (self , msg : t .CommandBase ) -> None :
674681 """
675682 Some commands are unhandled but frequently sent by devices on the network. To
@@ -693,9 +700,9 @@ async def on_zdo_relays_message(self, msg: c.ZDO.SrcRtgInd.Callback) -> None:
693700 ZDO source routing message callback
694701 """
695702
696- device = await self . _get_or_discover_device ( nwk = msg . DstAddr )
697-
698- if device is None :
703+ try :
704+ device = await self . _get_or_discover_device ( nwk = msg . DstAddr )
705+ except KeyError :
699706 LOGGER .warning (
700707 "Received a ZDO message from an unknown device: %s" , msg .DstAddr
701708 )
@@ -778,9 +785,9 @@ async def on_af_message(self, msg: c.AF.IncomingMsg.Callback) -> None:
778785 Handler for all non-ZDO messages.
779786 """
780787
781- device = await self . _get_or_discover_device ( nwk = msg . SrcAddr )
782-
783- if device is None :
788+ try :
789+ device = await self . _get_or_discover_device ( nwk = msg . SrcAddr )
790+ except KeyError :
784791 LOGGER .warning (
785792 "Received an AF message from an unknown device: %s" , msg .SrcAddr
786793 )
@@ -864,7 +871,7 @@ async def _watchdog_loop(self):
864871 return
865872
866873 @combine_concurrent_calls
867- async def _get_or_discover_device (self , nwk : t .NWK ) -> zigpy .device .Device | None :
874+ async def _get_or_discover_device (self , nwk : t .NWK ) -> zigpy .device .Device :
868875 """
869876 Finds a device by its NWK address. If a device does not exist in the zigpy
870877 database, attempt to look up its new NWK address. If it does not exist in the
@@ -880,23 +887,16 @@ async def _get_or_discover_device(self, nwk: t.NWK) -> zigpy.device.Device | Non
880887
881888 try :
882889 # XXX: Multiple responses may arrive but we only use the first one
883- ieee_addr_rsp = await self ._znp .request_callback_rsp (
884- request = c .ZDO .IEEEAddrReq .Req (
885- NWK = nwk ,
886- RequestType = c .zdo .AddrRequestType .SINGLE ,
887- StartIndex = 0 ,
888- ),
889- RspStatus = t .Status .SUCCESS ,
890- callback = c .ZDO .IEEEAddrRsp .Callback (
891- partial = True ,
892- NWK = nwk ,
893- ),
894- timeout = 5 , # We don't want to wait forever
895- )
890+ async with async_timeout .timeout (IEEE_ADDR_DISCOVERY_TIMEOUT ):
891+ _ , ieee , _ , _ , _ , _ = await self .zigpy_device .zdo .IEEE_addr_req (
892+ * {
893+ "NWKAddrOfInterest" : nwk ,
894+ "RequestType" : c .zdo .AddrRequestType .SINGLE ,
895+ "StartIndex" : 0 ,
896+ }.values ()
897+ )
896898 except asyncio .TimeoutError :
897- return None
898-
899- ieee = ieee_addr_rsp .IEEE
899+ raise KeyError (f"Unknown device: 0x{ nwk :04X} " )
900900
901901 try :
902902 device = self .get_device (ieee = ieee )
@@ -1276,7 +1276,7 @@ async def _send_zdo_request(
12761276 # Call the converter with the ZDO request's kwargs
12771277 req_factory , rsp_factory , zdo_rsp_factory = ZDO_CONVERTERS [cluster ]
12781278 request = req_factory (dst_addr , ** zdo_kwargs )
1279- callback = rsp_factory (dst_addr )
1279+ callback = rsp_factory (dst_addr , ** zdo_kwargs )
12801280
12811281 LOGGER .debug (
12821282 "Intercepted AP ZDO request %s(%s) and replaced with %s" ,
0 commit comments