summaryrefslogtreecommitdiff
path: root/core/profile.py
diff options
context:
space:
mode:
authorChristian Kolset <ckolset@colostate.edu>2026-08-13 11:09:03 -0600
committerChristian Kolset <ckolset@colostate.edu>2026-08-13 11:09:03 -0600
commit4d08be2656d5599caf60ab5163a9d2305b397daf (patch)
treed78e764e21995b47eca79d184460f14eb52cdd22 /core/profile.py
parent012a1093e3cb9a1b376fc3beee4df859ccfb8da5 (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.py28
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