问题 在python中获取友好的设备名称


我有一个2端口信号继电器通过USB串行接口连接到我的电脑。使用pyserial模块,我可以轻松控制这些继电器。但是,这是基于我事先知道设备分配给哪个COM端口(或/ dev-node)的假设。

对于我正在做的项目是不够的,因为我不想假设设备总是被分配到例如Windows中的COM7。我需要能够使用python在可能的平台(Win,Linux,OSX(我想这将类似于Linux方法))上以编程方式识别设备。或许正如标题所示,在系统中枚举USB设备并以某种方式获得更友好的名称。 Windows和Linux是最重要的支持平台。

任何帮助将不胜感激!

编辑:
似乎pyudev-module非常适合Linux系统。有没有人有过这方面的经验?


6526
2017-09-26 06:53


起源



答案:


关于Linux,如果您只需要枚举设备,您甚至可以跳过项目的pyudev依赖,并简单地解析输出 /sbin/udevadm info --export-db 命令(不需要root权限)。它将转储有关当前设备和类的所有信息,包括USB设备的USB产品ID,这些信息应足以识别USB到串行适配器。当然,你也可以用pyudev做到这一点。


7
2017-09-26 08:08





我知道这是一篇较老的帖子,但今天我一直在努力。 最后我使用wmi库进行python,因为我在Windows机器上(抱歉,我知道我的答案仅适用于Windows,但也许它会帮助某人)。

import wmi
c = wmi.WMI()
wql = "Select * From Win32_USBControllerDevice"
for item in c.query(wql):
    print item.Dependent.Caption

应该是这样的结果:

USB Root Hub
USB Root Hub
多产的USB转串口通讯端口(COM9)
USB Root Hub
USB Root Hub
USB复合设备
USB视频设备
USB音频设备
USB Root Hub
...略...

在这种情况下,您必须对Caption进行字符串解析才能找到COM端口。您还可以查看item.Dependent对象,以查看您可能认为相关的标题旁边的USB设备的其他属性:

instance of Win32_PnPEntity
{
    Caption = "USB Root Hub";
    ClassGuid = "{36fc9e60-c465-11cf-8056-444553540000}";
    ConfigManagerErrorCode = 0;
    ConfigManagerUserConfig = FALSE;
    CreationClassName = "Win32_PnPEntity";
    Description = "USB Root Hub";
    DeviceID = "USB\\ROOT_HUB\\4&32F13EF0&1";
    HardwareID = {"USB\\ROOT_HUB&VID8086&PID3A36&REV0000",     
                "USB\\ROOT_HUB&VID8086&PID3A36", "USB\\ROOT_HUB"};
    Manufacturer = "(Standard USB Host Controller)";
    Name = "USB Root Hub";
    PNPDeviceID = "USB\\ROOT_HUB\\4&32F13EF0&1";
    Service = "usbhub";
    Status = "OK";
    SystemCreationClassName = "Win32_ComputerSystem";
    SystemName = "001fbc0934d1";

};


3
2018-02-22 21:51





至少对于linux,你可以使用一些虚拟黑客来确定你的/ dev节点,例如在你附加设备之前和之后检查“ls / dev | grep ttyUSB”的输出。这在某种程度上也必须适用于OSX案例。一个好主意是使用subprocess.Popen()命令检查这些命令。至于窗户, 这个 可能会有所帮助。


2
2017-09-26 08:15





Windows:您可以提取USB信息 来自WMI但是 你需要成为管理员。示例是在.NET中,但您应该能够使用 Python WMI模块。这将使您可以访问USB识别字符串,其中可能包含有用的信息。对于FTDI串行设备,使用FTDI的DLL有一个捷径,它不需要特权访问。

Linux:所有可用的信息都在 /sys/bus/usb,也可以通过udev获得。 这看起来是一个很好的答案


2
2017-09-26 08:34





就Windows而言,您可以扫描注册表:

import _winreg as reg
from itertools import count

key = reg.OpenKey(reg.HKEY_LOCAL_MACHINE, 'HARDWARE\\DEVICEMAP\\SERIALCOMM')
try:
    for i in count():
        device, port = reg.EnumValue(key, i)[:2]
        print device, port
except WindowsError:
    pass

1
2017-09-26 08:40





如果可能的话会很棒,但根据我使用COM端口的商业设备的经验,情况并非如此。大多数情况下,您需要在软件中手动设置COM端口。这是一个烂摊子,特别是在Windows(至少XP)中,在某些情况下往往会改变com端口的数量。在某些设备中,软件中有一个自动发现功能,它向每个COM端口发送一条小消息并等待正确的答案。这当然只有在仪器实现某种识别命令时才有效。祝你好运。


0
2017-09-26 08:19