Feature request: lookup of port given device serial number

I’m using pio as part of Hardware in the Loop testing, using a SBC to run a self-hosted github actions runner, which has the hardware under test attached via USB. I used pio remote device list to determine the ports that correspond to the devices, which I added statically as environment variables on the runner, so that they can be changed fairly easily.

However, when more devices are added, or USB hubs changed, the assigned ports will also change.

What would be ideal is to be able to dynamically find the port that corresponds to a device’s serial number, which pio device list reports via SER=xxx in the hwid, and use that as part of the CI build. This would avoid having to update environment variables each time the USB devices change order.

As a workaround, I wanted to use the --json-output flag with jq to extract the information, but I’m not so familiar with jq. This is also made harder because the SER value isn’t reported as a separate property.

I’d be happy to implement this and submit a PR if this seems like a reasonable feature request.

If you’re on Linux, use /dev/serial/by-id/... paths (refer here) in upload_port and monitor_port. They will be symlinks to /dev/ttyXXX based on their USB serial number.


Thanks! I didn’t know that. I am running linux so this is a good workaround for my immediate need.

Would a cross-platform solution be a good thing to have? All the pieces are there from pyserial, we just need to make them more accessible via the pio command line.

Well technically the /dev/serial/by-id comes from the Linux kernel in this case, and uploader programs may not use pyserial at all. It is however true that 1. the serial monitor in PlatformIO is miniterm.py from pyserial and 2. some uploaders (e.g., esptool.py for ESP8266+ESP32) also use pyserial, which means they would likely acept a hwgrep:// expression as documented here and here, that would allow expressions such as monitor_port = hwgrep://0403:faf0 SNR=83852734 (USB VID:PID + serial number).

>python -m serial.tools.list_ports -v
    desc: Kommunikationsanschluss (COM1)
    hwid: ACPI\PNP0501\0
    desc: Silicon Labs CP210x USB to UART Bridge (COM5)
    hwid: USB VID:PID=10C4:EA60 SER=0001 LOCATION=1-6
2 ports found

So if PlatformIO were to do that lookup and pass the resolved (regular) serial port device name on to the programs, that would have some benefits for those programs that are not capable of this resolve. If there’s no such issue at Issues · platformio/platformio-core · GitHub yet, feel free to file one.

Another technical detail is that when PlatformIO auto-detects the upload or monitor port (i.e. when no monitor_port/upload_port is given, it does try to find the serial device matching a USB VID:PID if the board has those hardware IDs written in its board definition. Some have this (specifically branded, well-known boards), some don’t (often cloned boards where the USB-to-serial chipset is not set in stone). E.g., compare “OLIMEX ESP32-PoE”

against generic ESP32 dev board.

Also note that you can override those hardware IDs at runtime using scripting:


This still only allows for VID:PID lookups though-- in the case of multiple boards using the same USB-to-serial chip (with different serial numbers), this can’t be used.

1 Like

Thank you for the detailed response @maxgerhardt! Much appreciated. I’ll add an issue to the tracker.