From 2de7c30a274c792ad7e39c4a341fe1624bdf78c4 Mon Sep 17 00:00:00 2001 From: horrible-knots Date: Sun, 12 Oct 2025 19:28:19 -0400 Subject: [PATCH] Plumb timeout from --timeout through MeshInterface Fix C0301: Line too long Ignore the pylint for 6 positional arguments --- meshtastic/__main__.py | 4 ++++ meshtastic/ble_interface.py | 5 +++-- meshtastic/mesh_interface.py | 7 ++++--- meshtastic/serial_interface.py | 13 +++++++++++-- meshtastic/stream_interface.py | 12 ++++++++++-- meshtastic/tcp_interface.py | 4 +++- 6 files changed, 35 insertions(+), 10 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 002f1ec..08ecf57 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1364,6 +1364,7 @@ def common(): debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes, + timeout=args.timeout, ) elif args.host: try: @@ -1378,6 +1379,7 @@ def common(): debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes, + timeout=args.timeout, ) except Exception as ex: meshtastic.util.our_exit(f"Error connecting to {args.host}:{ex}", 1) @@ -1388,6 +1390,7 @@ def common(): debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes, + timeout=args.timeout, ) except FileNotFoundError: # Handle the case where the serial device is not found @@ -1425,6 +1428,7 @@ def common(): debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes, + timeout=args.timeout, ) except Exception as ex: meshtastic.util.our_exit( diff --git a/meshtastic/ble_interface.py b/meshtastic/ble_interface.py index e65d339..19d9a27 100644 --- a/meshtastic/ble_interface.py +++ b/meshtastic/ble_interface.py @@ -32,15 +32,16 @@ class BLEInterface(MeshInterface): class BLEError(Exception): """An exception class for BLE errors.""" - def __init__( + def __init__( # pylint: disable=R0917 self, address: Optional[str], noProto: bool = False, debugOut: Optional[io.TextIOWrapper]=None, noNodes: bool = False, + timeout: int = 300, ) -> None: MeshInterface.__init__( - self, debugOut=debugOut, noProto=noProto, noNodes=noNodes + self, debugOut=debugOut, noProto=noProto, noNodes=noNodes, timeout=timeout ) self.should_read = False diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 4ec9b80..c269209 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -90,7 +90,7 @@ class MeshInterface: # pylint: disable=R0902 super().__init__(self.message) def __init__( - self, debugOut=None, noProto: bool = False, noNodes: bool = False + self, debugOut=None, noProto: bool = False, noNodes: bool = False, timeout: int = 300 ) -> None: """Constructor @@ -99,13 +99,14 @@ class MeshInterface: # pylint: disable=R0902 link - just be a dumb serial client. noNodes -- If True, instruct the node to not send its nodedb on startup, just other configuration information. + timeout -- How long to wait for replies (default: 300 seconds) """ self.debugOut = debugOut self.nodes: Optional[Dict[str, Dict]] = None # FIXME self.isConnected: threading.Event = threading.Event() self.noProto: bool = noProto self.localNode: meshtastic.node.Node = meshtastic.node.Node( - self, -1 + self, -1, timeout=timeout ) # We fixup nodenum later self.myInfo: Optional[ mesh_pb2.MyNodeInfo @@ -119,7 +120,7 @@ class MeshInterface: # pylint: disable=R0902 self.failure = ( None # If we've encountered a fatal exception it will be kept here ) - self._timeout: Timeout = Timeout() + self._timeout: Timeout = Timeout(maxSecs=timeout) self._acknowledgment: Acknowledgment = Acknowledgment() self.heartbeatTimer: Optional[threading.Timer] = None random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it diff --git a/meshtastic/serial_interface.py b/meshtastic/serial_interface.py index a9d5dd7..88f17de 100644 --- a/meshtastic/serial_interface.py +++ b/meshtastic/serial_interface.py @@ -18,13 +18,22 @@ logger = logging.getLogger(__name__) class SerialInterface(StreamInterface): """Interface class for meshtastic devices over a serial link""" - def __init__(self, devPath: Optional[str]=None, debugOut=None, noProto: bool=False, connectNow: bool=True, noNodes: bool=False) -> None: + def __init__( + self, + devPath: Optional[str] = None, + debugOut=None, + noProto: bool = False, + connectNow: bool = True, + noNodes: bool = False, + timeout: int = 300 + ) -> None: """Constructor, opens a connection to a specified serial port, or if unspecified try to find one Meshtastic device by probing Keyword Arguments: devPath {string} -- A filepath to a device, i.e. /dev/ttyUSB0 (default: {None}) debugOut {stream} -- If a stream is provided, any debug serial output from the device will be emitted to that stream. (default: {None}) + timeout -- How long to wait for replies (default: 300 seconds) """ self.noProto = noProto @@ -57,7 +66,7 @@ class SerialInterface(StreamInterface): time.sleep(0.1) StreamInterface.__init__( - self, debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes + self, debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes, timeout=timeout ) def _set_hupcl_with_termios(self, f: TextIOWrapper): diff --git a/meshtastic/stream_interface.py b/meshtastic/stream_interface.py index a45c067..06ee28a 100644 --- a/meshtastic/stream_interface.py +++ b/meshtastic/stream_interface.py @@ -23,12 +23,20 @@ logger = logging.getLogger(__name__) class StreamInterface(MeshInterface): """Interface class for meshtastic devices over a stream link (serial, TCP, etc)""" - def __init__(self, debugOut: Optional[io.TextIOWrapper]=None, noProto: bool=False, connectNow: bool=True, noNodes: bool=False) -> None: + def __init__( # pylint: disable=R0917 + self, + debugOut: Optional[io.TextIOWrapper] = None, + noProto: bool = False, + connectNow: bool = True, + noNodes: bool = False, + timeout: int = 300 + ) -> None: """Constructor, opens a connection to self.stream Keyword Arguments: debugOut {stream} -- If a stream is provided, any debug serial output from the device will be emitted to that stream. (default: {None}) + timeout -- How long to wait for replies (default: 300 seconds) Raises: Exception: [description] @@ -49,7 +57,7 @@ class StreamInterface(MeshInterface): # FIXME, figure out why daemon=True causes reader thread to exit too early self._rxThread = threading.Thread(target=self.__reader, args=(), daemon=True, name="stream reader") - MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto, noNodes=noNodes) + MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto, noNodes=noNodes, timeout=timeout) # Start the reader thread after superclass constructor completes init if connectNow: diff --git a/meshtastic/tcp_interface.py b/meshtastic/tcp_interface.py index a324b90..732f37e 100644 --- a/meshtastic/tcp_interface.py +++ b/meshtastic/tcp_interface.py @@ -23,11 +23,13 @@ class TCPInterface(StreamInterface): connectNow: bool=True, portNumber: int=DEFAULT_TCP_PORT, noNodes:bool=False, + timeout: int = 300, ): """Constructor, opens a connection to a specified IP address/hostname Keyword Arguments: hostname {string} -- Hostname/IP address of the device to connect to + timeout -- How long to wait for replies (default: 300 seconds) """ self.stream = None @@ -42,7 +44,7 @@ class TCPInterface(StreamInterface): else: self.socket = None - super().__init__(debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes) + super().__init__(debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes, timeout=timeout) def __repr__(self): rep = f"TCPInterface({self.hostname!r}"