From 239f22a7c0ba24faa103ca73ac5f538afc8f26c8 Mon Sep 17 00:00:00 2001 From: Simon Dohmen Date: Thu, 7 Nov 2024 13:14:22 +0100 Subject: [PATCH 1/4] added new param exluded_com_ports changed default value of reported_arduino_id to None added closing serial connection if ids do not match --- pyproject.toml | 2 +- telemetrix/telemetrix.py | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4a041df..ddd8a02 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ find = {} # Scan the project directory with the default parameters [project] name = "telemetrix" -version = "1.42" +version = "1.43" authors = [ { name="Alan Yorinks", email="MisterYsLab@gmail.com" }, ] diff --git a/telemetrix/telemetrix.py b/telemetrix/telemetrix.py index 59b2ff1..3f607c0 100644 --- a/telemetrix/telemetrix.py +++ b/telemetrix/telemetrix.py @@ -43,6 +43,7 @@ class Telemetrix(threading.Thread): # noinspection PyPep8,PyPep8,PyPep8 def __init__(self, com_port=None, arduino_instance_id=1, + excluded_com_ports=[], arduino_wait=4, sleep_tune=0.000001, shutdown_on_exception=True, ip_address=None, ip_port=31335): @@ -56,6 +57,10 @@ def __init__(self, com_port=None, arduino_instance_id=1, :param arduino_instance_id: Match with the value installed on the arduino-telemetrix sketch. + :param excluded_com_ports: Excluded ports on auto com port detection. + This is needed to run multiple instances at the same + time on auto mode. + :param arduino_wait: Amount of time to wait for an Arduino to fully reset itself. @@ -105,6 +110,7 @@ def __init__(self, com_port=None, arduino_instance_id=1, # save input parameters as instance variables self.com_port = com_port self.arduino_instance_id = arduino_instance_id + self.excluded_com_ports = excluded_com_ports self.arduino_wait = arduino_wait self.sleep_tune = sleep_tune self.shutdown_on_exception = shutdown_on_exception @@ -217,7 +223,7 @@ def __init__(self, com_port=None, arduino_instance_id=1, self.firmware_version = [] # reported arduino instance id - self.reported_arduino_id = [] + self.reported_arduino_id = None # reported features self.reported_features = 0 @@ -347,7 +353,7 @@ def _find_arduino(self): print('Opening all potential serial ports...') the_ports_list = list_ports.comports() for port in the_ports_list: - if port.pid is None: + if port.pid is None or port.device in self.excluded_com_ports: continue try: self.serial_port = serial.Serial(port.device, 115200, @@ -377,9 +383,12 @@ def _find_arduino(self): self.serial_port.reset_input_buffer() self._get_arduino_id() - while self.reported_arduino_id is None: + retries = 50 + while self.reported_arduino_id is None and retries > 0: time.sleep(.2) + retries -= 1 if self.reported_arduino_id != self.arduino_instance_id: + self.serial_port.close() continue else: print('Valid Arduino ID Found.') From e7544d22ef06885197ffdf9bd870358b179b0ed8 Mon Sep 17 00:00:00 2001 From: Simon Dohmen Date: Thu, 7 Nov 2024 13:29:46 +0100 Subject: [PATCH 2/4] added try: to _ditigal_message to avoid IndexError: list index out of range error --- telemetrix/telemetrix.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/telemetrix/telemetrix.py b/telemetrix/telemetrix.py index 3f607c0..936dc49 100644 --- a/telemetrix/telemetrix.py +++ b/telemetrix/telemetrix.py @@ -2215,13 +2215,16 @@ def _digital_message(self, data): :param data: digital message """ - pin = data[0] - value = data[1] - - time_stamp = time.time() - if self.digital_callbacks[pin]: - message = [PrivateConstants.DIGITAL_REPORT, pin, value, time_stamp] - self.digital_callbacks[pin](message) + try: + pin = data[0] + value = data[1] + + time_stamp = time.time() + if self.digital_callbacks[pin]: + message = [PrivateConstants.DIGITAL_REPORT, pin, value, time_stamp] + self.digital_callbacks[pin](message) + except: + print('malformed message in _digital_message') def _firmware_message(self, data): """ From 0a5acefc775fbececddf1bff7cb87d9a01195ce9 Mon Sep 17 00:00:00 2001 From: Simon Dohmen Date: Thu, 7 Nov 2024 21:32:42 +0100 Subject: [PATCH 3/4] reverted closing connections if id does not match in _find_arduino because its dangerous - if used wrong you can terminate already existing connections with a console spammed with messages --- telemetrix/telemetrix.py | 1 - 1 file changed, 1 deletion(-) diff --git a/telemetrix/telemetrix.py b/telemetrix/telemetrix.py index 936dc49..38fac57 100644 --- a/telemetrix/telemetrix.py +++ b/telemetrix/telemetrix.py @@ -388,7 +388,6 @@ def _find_arduino(self): time.sleep(.2) retries -= 1 if self.reported_arduino_id != self.arduino_instance_id: - self.serial_port.close() continue else: print('Valid Arduino ID Found.') From c006fa5d30a6f2422b28d253efb0ab67990a2769 Mon Sep 17 00:00:00 2001 From: Simon Dohmen Date: Fri, 8 Nov 2024 02:02:58 +0100 Subject: [PATCH 4/4] replaced excluded ports with a singleton register class --- telemetrix/telemetrix.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/telemetrix/telemetrix.py b/telemetrix/telemetrix.py index 38fac57..4ea878c 100644 --- a/telemetrix/telemetrix.py +++ b/telemetrix/telemetrix.py @@ -30,6 +30,22 @@ # noinspection PyUnresolvedReferences from telemetrix.private_constants import PrivateConstants +class TelemetrixPortRegister: + """ + This is a Singleton Class to share active ports + used by Telemetrix instances. + + """ + _instance = None + + def __new__(self): + if self._instance is None: + self._instance = super(TelemetrixPortRegister, self).__new__(self) + self.active = [] + return self._instance + + def add(self, port): + self.active.append(port) # noinspection PyPep8,PyMethodMayBeStatic,GrazieInspection,PyBroadException,PyCallingNonCallable class Telemetrix(threading.Thread): @@ -43,11 +59,11 @@ class Telemetrix(threading.Thread): # noinspection PyPep8,PyPep8,PyPep8 def __init__(self, com_port=None, arduino_instance_id=1, - excluded_com_ports=[], arduino_wait=4, sleep_tune=0.000001, shutdown_on_exception=True, ip_address=None, ip_port=31335): + self.serial_port_register = TelemetrixPortRegister() """ :param com_port: e.g. COM3 or /dev/ttyACM0. @@ -57,10 +73,6 @@ def __init__(self, com_port=None, arduino_instance_id=1, :param arduino_instance_id: Match with the value installed on the arduino-telemetrix sketch. - :param excluded_com_ports: Excluded ports on auto com port detection. - This is needed to run multiple instances at the same - time on auto mode. - :param arduino_wait: Amount of time to wait for an Arduino to fully reset itself. @@ -110,7 +122,6 @@ def __init__(self, com_port=None, arduino_instance_id=1, # save input parameters as instance variables self.com_port = com_port self.arduino_instance_id = arduino_instance_id - self.excluded_com_ports = excluded_com_ports self.arduino_wait = arduino_wait self.sleep_tune = sleep_tune self.shutdown_on_exception = shutdown_on_exception @@ -352,8 +363,10 @@ def _find_arduino(self): print('Opening all potential serial ports...') the_ports_list = list_ports.comports() + + registered_ports = list(map(lambda p: p.port, self.serial_port_register.active)) for port in the_ports_list: - if port.pid is None or port.device in self.excluded_com_ports: + if port.pid is None or port.device in registered_ports: continue try: self.serial_port = serial.Serial(port.device, 115200, @@ -390,6 +403,7 @@ def _find_arduino(self): if self.reported_arduino_id != self.arduino_instance_id: continue else: + self.serial_port_register.add(serial_port) print('Valid Arduino ID Found.') self.serial_port.reset_input_buffer() self.serial_port.reset_output_buffer()