| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
- # port_scanner.py
- import serial.tools.list_ports
- def scan_ports() -> list[dict]:
- """Returns list of candidate KKL ports."""
- ports = serial.tools.list_ports.comports()
- candidates = []
-
- for port in ports:
- # Prioritize FTDI and common USB-to-Serial
- is_likely = False
- desc = port.description.lower()
- hwid = port.hwid.lower()
-
- if "ftdi" in desc or "ftdi" in hwid or "0403" in hwid:
- is_likely = True
- elif "usb" in desc or "ch340" in desc or "serial" in desc:
- is_likely = True
-
- candidates.append({
- "device": port.device,
- "description": port.description,
- "is_likely": is_likely
- })
-
- # Sort likely ports first
- candidates.sort(key=lambda x: not x["is_likely"])
- return candidates
- def auto_select() -> str | None:
- """Returns the best-guess port, or None if ambiguous or none found."""
- ports = scan_ports()
- if not ports:
- return None
-
- likely_ports = [p for p in ports if p["is_likely"]]
-
- if len(likely_ports) == 1:
- return likely_ports[0]["device"]
- elif len(likely_ports) > 1:
- # If multiple likely, return None to force user choice
- return None
- elif len(ports) > 0:
- # Fallback to first available if no obvious candidate
- return ports[0]["device"]
-
- return None
|