Getting friendly device names in python
Asked Answered
G

6

11

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?

Glottal answered 26/9, 2011 at 6:53 Comment(0)
B
7

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.

Borer answered 26/9, 2011 at 8:8 Comment(0)
D
5

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";
};
Diastase answered 22/2, 2013 at 21:51 Comment(0)
I
2

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.

Invalidate answered 26/9, 2011 at 8:15 Comment(0)
V
2

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.

Viand answered 26/9, 2011 at 8:34 Comment(0)
L
1

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
Lunette answered 26/9, 2011 at 8:40 Comment(0)
M
0

It will be great if this is possible, but in my experience with commercial equipments using COM ports this is not the case. Most of the times you need to set manually in the software the COM port. This is a mess, specially in windows (at least XP) that tends to change the number of the com ports in certain cases. In some equipment there is an autodiscovery feature in the software that sends a small message to every COM port and waits for the right answer. This of course only works if the instrument implements some kind of identification command. Good luck.

Methodology answered 26/9, 2011 at 8:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.