diff options
| author | Christian Kolset <ckolset@colostate.edu> | 2026-08-13 11:09:03 -0600 |
|---|---|---|
| committer | Christian Kolset <ckolset@colostate.edu> | 2026-08-13 11:09:03 -0600 |
| commit | 4d08be2656d5599caf60ab5163a9d2305b397daf (patch) | |
| tree | d78e764e21995b47eca79d184460f14eb52cdd22 /core/profile.py | |
| parent | 012a1093e3cb9a1b376fc3beee4df859ccfb8da5 (diff) | |
Re-detect serial device ports by identity when a profile loads on another machine
COM/tty numbers aren't stable across machines or replugs. Devices now save
their USB serial number and OS description alongside the port; on profile
load, if the saved port isn't present, ArduinoLayer.find_port_by_identity()
looks for a match and remaps it. Falls back to the saved port (device shows
ERROR) if nothing matches.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat (limited to 'core/profile.py')
| -rw-r--r-- | core/profile.py | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/core/profile.py b/core/profile.py index 1fa667a..c0ae5f1 100644 --- a/core/profile.py +++ b/core/profile.py @@ -325,9 +325,33 @@ class ProfileManager: # "name" is a display label, not a constructor arg — every device # factory builds its own default name internally, so apply it # after construction instead of passing it through. - custom_name = dev_cfg.get("name") + # "port_desc"/"port_serial" are identity metadata for port + # re-detection below, not constructor args either. + custom_name = dev_cfg.get("name") + port_desc = dev_cfg.get("port_desc", "") + port_serial = dev_cfg.get("port_serial", "") kwargs = {k: v for k, v in dev_cfg.items() - if k not in ("device_type", "name")} + if k not in ("device_type", "name", "port_desc", "port_serial")} + + # Re-map the saved port to whatever it enumerates as on *this* + # machine — COM/tty numbers aren't stable across machines (or + # even across replugs on some OSes). Only if the saved port + # isn't already present verbatim (same-machine reload — nothing + # to fix) and we have something to match against. + if not kwargs.get("simulate", True) and "port" in kwargs and (port_desc or port_serial): + from api_layers.arduino_layer import ArduinoLayer + current_ports = {dev for dev, _ in ArduinoLayer.list_ports()} + if kwargs["port"] not in current_ports: + found = ArduinoLayer.find_port_by_identity(port_desc, port_serial) + if found: + print(f"[Profile] '{dev_id}': port {kwargs['port']!r} not found, " + f"re-mapped to {found!r} by device identity") + kwargs["port"] = found + else: + print(f"[Profile] '{dev_id}': port {kwargs['port']!r} not found and " + f"no matching device on this machine — will show ERROR " + f"until reconfigured") + dev = factory(**kwargs) if custom_name: dev.info.name = custom_name |
