¿Una forma sencilla de consultar la información de los dispositivos USB conectados en Python?


¿Cómo podemos consultar la información de los dispositivos USB conectados en Python? Quiero obtener el nombre del dispositivo UID (por ejemplo: SonyEricsson W660), la ruta al dispositivo (por ejemplo: /dev/ttyACM0)

Y también cuál sería el mejor Parámetro de la información anterior para ser utilizado como la identificación del dispositivo cada vez que se conecta de nuevo? (UID?)

Estoy trabajando en Ubuntu 11.04.

ATM Tengo este código (usando PyUSB)

busses = usb.busses()
for bus in busses:
  devices = bus.devices
  for dev in devices:
    print repr(dev)
    print "Device:", dev.filename
    print "  idVendor: %d (0x%04x)" % (dev.idVendor, dev.idVendor)
    print "  idProduct: %d (0x%04x)" % (dev.idProduct, dev.idProduct)
    print "Manufacturer:", dev.iManufacturer
    print "Serial:", dev.iSerialNumber
    print "Product:", dev.iProduct

El problema es que no obtengo la salida deseada, pegaré un ejemplo:

<usb.legacy.Device object at 0x1653990>
Device: 
  idVendor: 4046 (0x0fce)
  idProduct: 53411 (0xd0a3)
Manufacturer: 1
Serial: 3
Product: 2

Primero I no obtengas el nombre del archivo, es lo más importante para mí. Asumo que es la parte de /dev/ttyACM0 etc. En segundo lugar, supongo que había algún UID de cada dispositivo USB, o debería usar tanto el id del proveedor como el del producto.

EDITAR: Aparentemente tengo algunos problemas de configuración, creo que estoy usando la biblioteca USB incorrecta. (utilizando libusb0.1) ATM. Es por eso que obtengo el Dispositivo (dev.filename) cadena vacía. Si alguien puede por favor decir que en qué sistema operativo está utilizando qué biblioteca USB y qué versión de PyUSB creo que es resolverá mis problemas.

Author: Josh Crozier, 2011-11-13

7 answers

Se me ocurre un código rápido como este.

Dado que todos los puertos USB se pueden acceder a través de/dev/ bus / usb / /

Para el ID generado, incluso si desconecta el dispositivo y lo vuelve a conectar [ podría ser algún otro puerto]. Será lo mismo.

import re
import subprocess
device_re = re.compile("Bus\s+(?P<bus>\d+)\s+Device\s+(?P<device>\d+).+ID\s(?P<id>\w+:\w+)\s(?P<tag>.+)$", re.I)
df = subprocess.check_output("lsusb")
devices = []
for i in df.split('\n'):
    if i:
        info = device_re.match(i)
        if info:
            dinfo = info.groupdict()
            dinfo['device'] = '/dev/bus/usb/%s/%s' % (dinfo.pop('bus'), dinfo.pop('device'))
            devices.append(dinfo)
print devices

La salida de muestra aquí será:

[
{'device': '/dev/bus/usb/001/009', 'tag': 'Apple, Inc. Optical USB Mouse [Mitsumi]', 'id': '05ac:0304'},
{'device': '/dev/bus/usb/001/001', 'tag': 'Linux Foundation 2.0 root hub', 'id': '1d6b:0002'},
{'device': '/dev/bus/usb/001/002', 'tag': 'Intel Corp. Integrated Rate Matching Hub', 'id': '8087:0020'},
{'device': '/dev/bus/usb/001/004', 'tag': 'Microdia ', 'id': '0c45:641d'}
]
 38
Author: meson10,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-20 17:23:51

Si está trabajando en Windows, puede usar pywin32.

He encontrado un ejemplo aquí:

import win32com.client

wmi = win32com.client.GetObject ("winmgmts:")
for usb in wmi.InstancesOf ("Win32_USBHub"):
    print usb.DeviceID
 32
Author: joaquin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-24 06:06:45

Puedes probar enlaces libusb

 2
Author: wRAR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-13 09:19:22

Cuando corro tu código, obtengo la siguiente salida, por ejemplo.

<usb.Device object at 0xef38c0>
Device: 001
  idVendor: 7531 (0x1d6b)
  idProduct: 1 (0x0001)
Manufacturer: 3
Serial: 1
Product: 2

Cabe destacar que a) Tengo usb.Device objetos mientras que usted tiene usb.legacy.Device objetos, y b) Tengo nombres de archivo de dispositivo.

Cada usb.Bus tiene un campo dirname y cada usb.Device tiene el nombre del archivo. Como puedes ver, el nombre de archivo es algo así como 001, y también lo es el nombre de dir. Puede combinarlos para obtener el archivo de bus. Para dirname=001 y filname=001, debería ser algo así como /dev/bus/usb/001/001.

Usted debe primero, aunque averiguar lo que este "usb.legacy " situación es. Estoy ejecutando la última versión y ni siquiera tengo un submódulo legacy.

Finalmente, debe usar los campos idVendor y idProduct para identificar de forma única el dispositivo cuando está conectado.

 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-18 13:17:19

Para un sistema con usb heredado regresando y libusb-1.0, este enfoque funcionará para recuperar las diversas cadenas reales. Muestro el proveedor y el producto como ejemplos. Puede causar algunas E / S, porque en realidad lee la información del dispositivo (al menos la primera vez, de todos modos.) Algunos dispositivos no proporcionan esta información, por lo que la presunción de que lo hacen lanzará una excepción en ese caso; eso está bien, así que pasamos.

import usb.core
import usb.backend.libusb1

busses = usb.busses()
for bus in busses:
    devices = bus.devices
    for dev in devices:
        if dev != None:
            try:
                xdev = usb.core.find(idVendor=dev.idVendor, idProduct=dev.idProduct)
                if xdev._manufacturer is None:
                    xdev._manufacturer = usb.util.get_string(xdev, xdev.iManufacturer)
                if xdev._product is None:
                    xdev._product = usb.util.get_string(xdev, xdev.iProduct)
                stx = '%6d %6d: '+str(xdev._manufacturer).strip()+' = '+str(xdev._product).strip()
                print stx % (dev.idVendor,dev.idProduct)
            except:
                pass
 1
Author: fyngyrz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-03 23:35:00

Para Linux, escribí un script llamado find_port.py que puedes encontrar aquí: https://github.com/dhylands/usb-ser-mon/blob/master/find_port.py

Utiliza pyudev para enumerar todos los dispositivos tty, y puede coincidir en varios atributos.

Utilice la opción list list para mostrar todos los puertos serie USB conocidos y sus atributos. Puede filtrar por VID, PID, número de serie o nombre del proveedor. Use help help para ver las opciones de filtrado.

Find_port.py imprime el nombre /dev / ttyXXX en lugar del / dev / usb/... nombre.

 1
Author: Dave Hylands,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-27 14:52:10

Si solo necesita el nombre del dispositivo aquí es un pequeño truco que escribí en bash. Para ejecutarlo en python necesita el siguiente fragmento. Simplemente reemplace $1 y $2 con el número de bus y el número de dispositivo, por ejemplo, 001 o 002.

import os
os.system("lsusb | grep \"Bus $1 Device $2\" | sed 's/\// /' | awk '{for(i=7;i<=NF;++i)print $i}'")

Alternativamente puede guardarlo como un script bash y ejecutarlo desde allí también. Solo guárdalo como un script bash como foo.sh hazlo ejecutable.

#!/bin/bash
myvar=$(lsusb | grep "Bus $1 Device $2" | sed 's/\// /' | awk '{for(i=7;i<=NF;++i)print $i}')
echo $myvar

Luego llámelo en el script python como

import os
os.system('foo.sh')
 0
Author: Qasim Ayyaz Khan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-14 09:11:04