Получение дружественных имен устройств в python

У меня есть 2-портовое сигнальное реле, подключенное к компьютеру через последовательный интерфейс USB. Используя модуль pyserial, я могу легко управлять этими реле. Однако это основано на предположении, что я заранее знаю, какой COM-порт (или/dev- node) назначен устройству.

Для проекта я делаю это недостаточно, так как я не хочу предполагать, что устройство всегда назначается, например, COM7 в Windows. Мне нужно иметь возможность идентифицировать устройство программно на всех возможных платформах (Win, Linux, OSX (который, я думаю, будет похож на подход Linux)), используя python. Возможно, по словам главы, перечислить USB-устройства в системе и как-то получить для них более дружественные имена. Windows и Linux являются наиболее важными платформами для поддержки.

Любая помощь будет принята с благодарностью!

EDIT:
Похоже, что pudev-модуль будет хорошо подходить для Linux-систем. Кто-нибудь имел опыт с этим?

Ответ 1

Что касается Linux, если вам нужно всего лишь перечислить устройства, вы можете даже пропустить pudev-зависимость для своего проекта и просто проанализировать вывод команды /sbin/udevadm info --export-db (не требуя привилегий root). Он сбрасывает всю информацию о существующих устройствах и классах, включая идентификаторы USB-продуктов для USB-устройств, которые должны быть более чем достаточно, чтобы идентифицировать ваши адаптеры USB-последовательный. Конечно, вы также можете сделать это с помощью pudev.

Ответ 2

Я знаю, что это старый пост, но я боролся с ним сегодня. В конечном итоге я использовал библиотеку wmi для python, поскольку я работаю на компьютере с Windows (извините, я знаю, что мой ответ применим только к Windows, но, возможно, он кому-нибудь поможет).

Сначала установите пакет, используя pip:

pip install wmi

затем

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
Prolific USB-to-Serial Comm Port (COM9) Корневой концентратор USB
USB Root Hub
USB композитное устройство
USB-видеоустройство USB-аудиоустройство
USB Root Hub
... чик...

В этом случае вам нужно будет проанализировать строку Caption, чтобы найти COM-порт. Вы также можете посмотреть только на элемент. Зависимый объект, чтобы увидеть другие атрибуты устройства USB рядом с Caption, которые вы можете найти соответствующими:

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

По крайней мере, для linux вы можете использовать некоторые фиктивные хаки для определения вашего /dev node, путем проверки, например, вывода "ls/dev | grep ttyUSB" до и после подключения вашего устройства. Это как-то должно применяться также и для случая OSX. Хорошая идея - проверить эти команды, используя что-то вроде команды subprocess.Popen(). Что касается окон, этот может быть полезен.

Ответ 4

Windows: вы можете вывести информацию USB из WMI, но вам нужно быть администратором. Примеры приведены в .NET, но вы должны иметь возможность использовать Python WMI module. Это даст вам доступ к строкам идентификации USB, которые могут содержать полезную информацию. Для последовательных устройств FTDI существует короткий отрезок с использованием FTDI DLL, который не требует привилегированного доступа.

Linux: вся доступная информация находится под /sys/bus/usb, а также доступна через udev. Это похоже на хороший ответ.

Ответ 5

Что касается 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

Ответ 6

Было бы здорово, если это возможно, но по моему опыту использования коммерческих устройств с использованием COM-портов это не так. В большинстве случаев вам нужно вручную установить в ПО COM-порт. Это беспорядок, особенно в Windows (по крайней мере XP), который в некоторых случаях имеет тенденцию к изменению количества COM-портов. В некоторых устройствах есть функция автообнаружения в программном обеспечении, которая отправляет небольшое сообщение на каждый COM-порт и ждет ответа. Это, конечно, работает только в том случае, если инструмент выполняет какую-то команду идентификации. Удачи.