Получение дружественных имен устройств в 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-порт и ждет ответа. Это, конечно, работает только в том случае, если инструмент выполняет какую-то команду идентификации. Удачи.