From f0ee488c785755630e726ba10a6621143cfcaa2a Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Mon, 24 Feb 2025 18:13:21 +0100 Subject: [PATCH 01/14] test with com0com --- freedata_server/list_ports_winreg.py | 150 +++++++++++++++++++++++++++ freedata_server/serial_ports.py | 10 +- 2 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 freedata_server/list_ports_winreg.py diff --git a/freedata_server/list_ports_winreg.py b/freedata_server/list_ports_winreg.py new file mode 100644 index 00000000..afb78730 --- /dev/null +++ b/freedata_server/list_ports_winreg.py @@ -0,0 +1,150 @@ +#! python +# +# Enumerate serial ports on Windows including a human readable description +# and hardware information using winreg. +# +# Using winreg helps find virtual comports + +try: + # Python 3.X + import winreg +except ImportError: + # Python 2.7 compatibility + try: + import _winreg as winreg + except ImportError: + winreg = None + +from serial.tools import list_ports_common +from serial.tools import list_ports_windows + +SERIAL_REGISTRY_PATH = 'HARDWARE\\DEVICEMAP\\SERIALCOMM' + + +def regval_to_listport(winport): + """Convert a windows port from registry key to pyserial's ListPortInfo. + + Args: + winport (tuple): Windows registry value (description, device, value). + + Returns: + listport (ListPortInfo): comport device details. + """ + # Create the ListPortInfo + description, device, _ = winport + listport = list_ports_common.ListPortInfo(device) + + # Format the description like other ListPortInfo + description = description.replace('\\Device\\', '') + listport.description = "{} ({})".format(description, device) + + return listport + + +# end regval_to_listport + + +def winreg_comports(): + """Return windows comports found in the registry. + + See Also: + list_ports_winreg.comports(), list_ports_winreg.comports_list(), + list_ports_windows.comports() + + Note: + This should include virtual comports, and it is significantly faster + than list_ports_windows.comports(). However, list_ports_windows has far + more information. comports() contains all list_ports_windows.comports() + and winreg_comports() that were not found from list_ports_windows. + + Returns: + comports (list): Sorted list of ListPortInfo. + """ + try: + # Get the Serial Coms registry + key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, SERIAL_REGISTRY_PATH) + + # Get key info - number of values (subkeys, num_vals, last_modified) + num_values = winreg.QueryInfoKey(key)[1] + + # Make a generator of comports + for i in range(num_values): + # get registry value for the comport + value = winreg.EnumValue(key, i) + yield regval_to_listport(value) + + # Close the registry key + winreg.CloseKey(key) + except (AttributeError, WindowsError, EnvironmentError): + # winreg is None or there was a key error + pass + + +# end winreg_comports + + +def comports_list(): + """Return a list of comports found from list_ports_windows and comports + found in the window registry. + + See Also: + list_ports_winreg.comports(), list_ports_winreg.winreg_comports(), + list_ports_windows.comports() + + Note: + This should include virtual comports. This method contains all + list_ports_windows.comports() and winreg_comports() that were not found + from list_ports_windows. + + Returns: + comports (list): List of ListPortInfo comport details. + """ + comports = list(list_ports_windows.comports()) + + comports[len(comports):] = [li for li in winreg_comports() + if li not in comports] + + return comports + + +# end comports_list + + +def comports(include_links=False): + """Generator for comports found from list ports windows and comports found + in the windows registry. + + See Also: + list_ports_winreg.comports_list(), list_ports_winreg.winreg_comports(), + list_ports_windows.comports() + + Note: + This should include virtual comports. This method contains all + list_ports_windows.comports() and winreg_comports() that were not found + from list_ports_windows. + + Yields: + comport (ListPortInfo): Comport details. + + Returns: + comports (generator): Generator of ListPortInfo comports. + """ + existing = [] + for comport in list_ports_windows.comports(): + existing.append(comport) + yield comport + + for li in winreg_comports(): + if li not in existing: + existing.append(li) + yield li + + +# end comports + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# test +if __name__ == '__main__': + for port, desc, hwid in sorted(comports()): + print("%s: %s [%s]" % (port, desc, hwid)) \ No newline at end of file diff --git a/freedata_server/serial_ports.py b/freedata_server/serial_ports.py index d9cf1dfb..f874314e 100644 --- a/freedata_server/serial_ports.py +++ b/freedata_server/serial_ports.py @@ -1,9 +1,17 @@ import serial.tools.list_ports +import list_ports_winreg import helpers +import sys + + def get_ports(): serial_devices = [] - ports = serial.tools.list_ports.comports(include_links=False) + if sys.platform == 'win32': + ports = serial.tools.list_ports.comports(include_links=False) + else: + ports = list_ports_winreg.comports(include_links=False) + for port, desc, hwid in ports: # calculate hex of hwid if we have unique names crc_hwid = helpers.get_crc_16(bytes(hwid, encoding="utf-8")) From 644f34529309340be9a3d4279e988411c5bbabcf Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Mon, 24 Feb 2025 18:16:13 +0100 Subject: [PATCH 02/14] test with com0com --- freedata_server/serial_ports.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/freedata_server/serial_ports.py b/freedata_server/serial_ports.py index f874314e..89aa7fbc 100644 --- a/freedata_server/serial_ports.py +++ b/freedata_server/serial_ports.py @@ -8,9 +8,10 @@ def get_ports(): serial_devices = [] if sys.platform == 'win32': - ports = serial.tools.list_ports.comports(include_links=False) - else: ports = list_ports_winreg.comports(include_links=False) + else: + + ports = serial.tools.list_ports.comports(include_links=False) for port, desc, hwid in ports: # calculate hex of hwid if we have unique names From d1c26950335ae8f1f9e71950e9eab67b8185a695 Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:51:33 +0100 Subject: [PATCH 03/14] attempt overriding ptt port --- .../src/components/settings_hamlib.vue | 25 +++++++++++++++++++ .../src/components/settings_serial_ptt.vue | 24 ++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/freedata_gui/src/components/settings_hamlib.vue b/freedata_gui/src/components/settings_hamlib.vue index 8da65c5d..a7654bde 100644 --- a/freedata_gui/src/components/settings_hamlib.vue +++ b/freedata_gui/src/components/settings_hamlib.vue @@ -442,6 +442,31 @@ const settings = ref({ + +
+ + + +
+
+ +
+ + + +