Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting friendly device names in python

I have an 2-port signal relay connected to my computer via a USB serial interface. Using the pyserial module I can control these relays with ease. However, this is based on the assumption that I know beforehand which COM-port (or /dev-node) the device is assigned to.

For the project I'm doing that's not enough since I don't want to assume that the device always gets assigned to for example COM7 in Windows. I need to be able to identify the device programatically across the possible platforms (Win, Linux, OSX (which I imagine would be similar to the Linux approach)), using python. Perhaps by, as the title suggests, enumerate USB-devices on the system and somehow get more friendly names for them. Windows and Linux being the most important platforms to support.

Any help would be greatly appreciated!

EDIT:
Seems like the pyudev-module would be a good fit for Linux-systems. Has anyone had any experience with that?

like image 948
manneorama Avatar asked Sep 26 '11 06:09

manneorama


5 Answers

Regarding Linux, if all you need is to enumerate devices, you can even skip pyudev dependency for your project, and simply parse the output of /sbin/udevadm info --export-db command (does not require root privileges). It will dump all information about present devices and classes, including USB product IDs for USB devices, which should be more then enough to identify your USB-to-serial adapters. Of course, you can also do this with pyudev.

like image 55
abbot Avatar answered Nov 10 '22 00:11

abbot


I know this is an older post, but I was struggling with it today. Ultimately I used the wmi library for python as I'm on a Windows machine (sorry, I know my answer only applies to Windows, but maybe it'll help someone).

Install the package using pip first:

pip install wmi

then

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

Should result with something like:

USB Root Hub
USB Root Hub
Prolific USB-to-Serial Comm Port (COM9) USB Root Hub
USB Root Hub
USB Composite Device
USB Video Device USB Audio Device
USB Root Hub
...snip...

In this case, you'd have to string parse the Caption to find the COM port. You can also take a look at just the item. Dependent object to see other attributes of the USB device beside Caption that you may find relevant:

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";
};
like image 5
Taylor Hanson Avatar answered Nov 10 '22 00:11

Taylor Hanson


At least for linux, you can use some dummy hacks to determine your /dev node, by inspecting for example the output of "ls /dev | grep ttyUSB" before and after you attach your device. This somehow must apply as well for the OSX case. A good idea is to inspect those commands using something like the subprocess.Popen() command. As for windows, this might be helpful.

like image 2
hymloth Avatar answered Nov 09 '22 23:11

hymloth


Windows: you can pull USB information from WMI, but you need to be administrator. The examples are in .NET, but you should be able to use the Python WMI module. This will give you access to USB identification strings, which may contain useful information. For FTDI serial devices there is a short cut using FTDI's DLL, which does not require privileged access.

Linux: all the available information is under /sys/bus/usb, and also available through udev. This looks like a good answer.

like image 2
Adrian Cox Avatar answered Nov 09 '22 23:11

Adrian Cox


As far as Windows goes, you could scan the registry:

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
like image 1
zeekay Avatar answered Nov 09 '22 23:11

zeekay