async def scan_modules(self, num_tries: int = 3, timeout_msec: int = 3000) -> None: """Scan for modules on the bus. This is a convenience coroutine which handles all the logic when scanning modules on the bus. Because of heavy bus traffic, not all modules might respond to a scan command immediately. The coroutine will make 'num_tries' attempts to send a scan command and waits 'timeout_msec' after the last module response before proceeding to the next try. :param int num_tries: Scan attempts (default=3) :param int timeout_msec: Timeout in msec for each try (default=3000) """ segment_coupler_ids = ( self.segment_coupler_ids if self.segment_coupler_ids else [0] ) for _ in range(num_tries): for segment_id in segment_coupler_ids: if segment_id == self.local_seg_id: segment_id = 0 await self.send_command( PckGenerator.generate_address_header( LcnAddr(segment_id, 3, True), self.local_seg_id, True ) + PckGenerator.empty() ) # Wait loop which is extended on every serial number received while True: try: await asyncio.wait_for( self.module_serial_number_received.acquire(), timeout_msec / 1000, ) except asyncio.TimeoutError: break
async def ping(self) -> bool: """Send a command that does nothing and request an acknowledgement.""" return await self.send_command(True, PckGenerator.empty())