44
55from __future__ import annotations
66
7- from asyncio import gather , sleep
7+ from asyncio import Task , create_task , gather , sleep
88from collections .abc import Callable , Coroutine
99from datetime import datetime , timedelta
1010import logging
@@ -78,6 +78,8 @@ def __init__(
7878 self ._unsubscribe_node_join : Callable [[], None ] | None = None
7979 self ._unsubscribe_node_rejoin : Callable [[], None ] | None = None
8080
81+ self ._discover_sed_tasks : dict [str , Task [bool ]] = {}
82+
8183 # region - Properties
8284
8385 @property
@@ -221,20 +223,26 @@ async def node_awake_message(self, response: PlugwiseResponse) -> bool:
221223 await self ._notify_node_event_subscribers (NodeEvent .AWAKE , mac )
222224 self ._awake_discovery [mac ] = response .timestamp
223225 return True
224- if self ._register .network_address (mac ) is None :
226+ address = self ._register .network_address (mac )
227+ if address is None :
225228 if self ._register .scan_completed :
226229 return True
227230 _LOGGER .debug (
228231 "Skip node awake message for %s because network registry address is unknown" ,
229232 mac ,
230233 )
231- return False
232- address = self ._register .network_address (mac )
233- if (address := self ._register .network_address (mac )) is not None :
234- if self ._nodes .get (mac ) is None :
235- return await self ._discover_battery_powered_node (address , mac )
236- else :
237- raise NodeError ("Unknown network address for node {mac}" )
234+ return True
235+
236+ if self ._nodes .get (mac ) is None :
237+ if (
238+ self ._discover_sed_tasks .get (mac ) is None
239+ or self ._discover_sed_tasks [mac ].done ()
240+ ):
241+ self ._discover_sed_tasks [mac ] = create_task (
242+ self ._discover_battery_powered_node (address , mac )
243+ )
244+ else :
245+ _LOGGER .debug ("duplicate maintenance awake discovery for %s" , mac )
238246 return True
239247
240248 async def node_join_available_message (self , response : PlugwiseResponse ) -> bool :
@@ -293,12 +301,12 @@ async def discover_network_coordinator(self, load: bool = False) -> bool:
293301
294302 # Validate the network controller is online
295303 # try to ping first and raise error at stick timeout
304+ ping_request = NodePingRequest (
305+ self ._controller .send ,
306+ bytes (self ._controller .mac_coordinator , UTF8 ),
307+ retries = 1 ,
308+ )
296309 try :
297- ping_request = NodePingRequest (
298- self ._controller .send ,
299- bytes (self ._controller .mac_coordinator , UTF8 ),
300- retries = 1 ,
301- )
302310 ping_response = await ping_request .send ()
303311 except StickTimeout as err :
304312 raise StickError (
@@ -368,13 +376,20 @@ async def get_node_details(
368376 ping_request = NodePingRequest (
369377 self ._controller .send , bytes (mac , UTF8 ), retries = 1
370378 )
371- ping_response = await ping_request .send (suppress_node_errors = True )
379+ try :
380+ ping_response = await ping_request .send (suppress_node_errors = True )
381+ except StickError :
382+ return (None , None )
372383 if ping_response is None :
373384 return (None , None )
385+
374386 info_request = NodeInfoRequest (
375387 self ._controller .send , bytes (mac , UTF8 ), retries = 1
376388 )
377- info_response = await info_request .send ()
389+ try :
390+ info_response = await info_request .send ()
391+ except StickError :
392+ return (None , None )
378393 return (info_response , ping_response )
379394
380395 async def _discover_battery_powered_node (
@@ -424,21 +439,9 @@ async def _discover_node(
424439 self ._create_node_object (mac , address , node_info .node_type )
425440
426441 # Forward received NodeInfoResponse message to node
427- await self ._nodes [mac ].update_node_details (
428- node_info .firmware ,
429- node_info .hardware ,
430- node_info .node_type ,
431- node_info .timestamp ,
432- node_info .relay_state ,
433- node_info .current_logaddress_pointer ,
434- )
442+ await self ._nodes [mac ].message_for_node (node_info )
435443 if node_ping is not None :
436- self ._nodes [mac ].update_ping_stats (
437- node_ping .timestamp ,
438- node_ping .rssi_in ,
439- node_ping .rssi_out ,
440- node_ping .rtt ,
441- )
444+ await self ._nodes [mac ].message_for_node (node_ping )
442445 await self ._notify_node_event_subscribers (NodeEvent .DISCOVERED , mac )
443446 return True
444447
@@ -501,7 +504,6 @@ async def _unload_discovered_nodes(self) -> None:
501504 # region - Network instance
502505 async def start (self ) -> None :
503506 """Start and activate network."""
504-
505507 self ._register .quick_scan_finished (self ._discover_registered_nodes )
506508 self ._register .full_scan_finished (self ._discover_registered_nodes )
507509 await self ._register .start ()
@@ -523,6 +525,9 @@ async def discover_nodes(self, load: bool = True) -> bool:
523525 async def stop (self ) -> None :
524526 """Stop network discovery."""
525527 _LOGGER .debug ("Stopping" )
528+ for task in self ._discover_sed_tasks .values ():
529+ if not task .done ():
530+ task .cancel ()
526531 self ._is_running = False
527532 self ._unsubscribe_to_protocol_events ()
528533 await self ._unload_discovered_nodes ()
0 commit comments