You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python通过Product ID和Vendor ID查找设备所连接的端口(如/dev/ttyACM0等)

Finding Serial Port Path by VID/PID in Python

Alright, let's figure out how to locate the serial port path (like /dev/ttyACM0) for a device using its Vendor ID (VID) and Product ID (PID) with Python. I'll walk you through two solid approaches—one using a handy library, and another that works without any extra installs.

The pyudev library is built specifically for interacting with Linux udev devices, so it's clean and reliable for this task.

First, install the library:

pip install pyudev

Then use this code snippet to find your device's port:

import pyudev

def find_device_port(vid, pid):
    # Convert VID/PID to lowercase hex strings (handles both int and string inputs)
    vid_str = f"{vid:04x}" if isinstance(vid, int) else vid.lower()
    pid_str = f"{pid:04x}" if isinstance(pid, int) else pid.lower()

    context = pyudev.Context()
    # Iterate over all tty devices
    for device in context.list_devices(subsystem='tty'):
        # Find the parent USB device (where VID/PID are stored)
        usb_parent = device.find_parent('usb', 'usb_device')
        if usb_parent:
            # Match the VID/PID
            if (usb_parent.get('ID_VENDOR_ID') == vid_str 
                and usb_parent.get('ID_MODEL_ID') == pid_str):
                return device.device_node  # Returns path like /dev/ttyACM0
    return None

# Example usage: Replace with your device's VID and PID
target_vid = 0x0483  # Can also pass as string "0483"
target_pid = 0x5740  # Or string "5740"
port = find_device_port(target_vid, target_pid)

if port:
    print(f"Found your device at: {port}")
else:
    print("Device not connected, or no matching port found.")

Method 2: Parsing sysfs (No Third-Party Libraries)

If you don't want to install extra packages, you can directly read from the Linux sysfs filesystem, which exposes device metadata.

import os

def find_device_port(vid, pid):
    vid_str = f"{vid:04x}" if isinstance(vid, int) else vid.lower()
    pid_str = f"{pid:04x}" if isinstance(pid, int) else pid.lower()
    tty_class_path = '/sys/class/tty'

    for tty_device in os.listdir(tty_class_path):
        # Follow the symlink to the device's actual path
        device_symlink = os.path.join(tty_class_path, tty_device, 'device')
        if not os.path.exists(device_symlink):
            continue
        
        real_device_path = os.path.realpath(device_symlink)
        # Skip non-USB devices
        if 'usb' not in real_device_path:
            continue
        
        # Read VID and PID from sysfs files
        vid_file = os.path.join(real_device_path, 'idVendor')
        pid_file = os.path.join(real_device_path, 'idProduct')
        if not os.path.exists(vid_file) or not os.path.exists(pid_file):
            continue
        
        with open(vid_file, 'r') as f:
            current_vid = f.read().strip()
        with open(pid_file, 'r') as f:
            current_pid = f.read().strip()
        
        if current_vid == vid_str and current_pid == pid_str:
            return f"/dev/{tty_device}"
    return None

# Example usage
target_vid = 0x1a86  # CH340 VID
target_pid = 0x7523  # CH340 PID
port = find_device_port(target_vid, target_pid)
print(port if port else "Device not found.")

Important Notes

  • Permissions: Ensure your user has access to serial ports. On most Linux systems, add yourself to the dialout group with:
    sudo usermod -aG dialout $USER
    
    Log out and back in for this change to take effect.
  • Duplicate Devices: If multiple devices share the same VID/PID, both methods will return the first matching port. To distinguish them, you can add checks for the device's serial number (look for ID_SERIAL in pyudev, or the serial file in sysfs).
  • VID/PID Format: You can pass VID/PID as integers (e.g., 0x1234) or lowercase hex strings (e.g., "1234").

内容的提问来源于stack exchange,提问作者mekanizm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:54:10