我有一个2端口信号继电器通过USB串行接口连接到我的电脑。 使用pyserial模块,我可以轻松地控制这些继电器。 但是,这是基于这样的假设:我事先知道设备分配给哪个COM端口(或/ dev-node)。
对于我这样做的项目来说,这还不够,因为我不想假定设备总是被分配给例如Windows中的COM7。 我需要能够使用python在可能的平台(Win,Linux,OSX(我认为它将类似于Linux方法))中编程式地识别设备。 也许正如标题所示,在系统上枚举USB设备,并以某种方式为它们获得更友好的名称。 Windows和Linux是最重要的支持平台。
任何帮助将不胜感激!
编辑:
似乎pyudev模块将非常适合Linux系统。 有没有人有任何经验呢?
关于Linux,如果您只需要枚举设备,您甚至可以跳过项目的pyudev依赖项,并简单地解析/sbin/udevadm info --export-db
命令的输出(不需要root权限)。 它将转储有关当前设备和类的所有信息,包括USB设备的USB产品ID,这些信息应该足以识别您的USB转串口适配器。 当然,你也可以用pyudev来做到这一点。
我知道这是一个较旧的帖子,但是我今天正在努力。 最后,我使用了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根集线器
USB根集线器
多产的USB串口通讯端口(COM9)
USB根集线器
USB根集线器
USB复合设备
USB视频设备
USB音频设备
USB根集线器
…略…
在这种情况下,您必须对Caption进行字符串解析才能找到COM端口。 您也可以查看item.Dependent对象,查看您可能发现的与Caption相关的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";
};
至少对于linux来说,通过在附加设备之前和之后检查“ls / dev | grep ttyUSB”的输出,您可以使用一些虚拟hack来确定您的/ dev节点。 这在某种程度上也必须适用于OSX的情况。 一个好主意是使用诸如subprocess.Popen()命令来检查这些命令。 至于窗户, 这可能会有所帮助。
Windows:可以从WMI中获取USB信息,但需要成为管理员 。 这些例子是在.NET中,但是你应该能够使用Python WMI模块 。 这将使您可以访问USB标识字符串,其中可能包含有用的信息。 对于FTDI串行设备,可以使用FTDI的DLL进行快捷方式,不需要特权访问。
Linux:所有可用的信息都在/sys/bus/usb
,也可以通过udev获得。 这看起来是一个很好的答案 。
就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
如果这是可能的,那将是非常好的,但是根据我使用COM端口的商业设备的经验,事实并非如此。 大多数情况下,您需要在软件中手动设置COM端口。 这是一团糟,特别是在Windows(至少XP),在某些情况下,往往会改变COM端口的数量。 在某些设备中,软件中有一个自动发现功能,它会向每个COM端口发送一条小消息,并等待正确答案。 这当然只有在仪器执行某种识别命令时才有效。 祝你好运。