nobackenderror - usb.core python
¿Una forma sencilla de consultar información de dispositivos USB conectados en Python? (7)
Cuando ejecuto 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 objetos usb.Device
mientras que usted tiene objetos usb.legacy.Device
, yb) Tengo nombres de archivos de dispositivo.
Cada usb.Bus
tiene un campo dirname
y cada usb.Device
tiene el nombre del archivo. Como puede ver, el nombre del archivo es algo así como 001
, y también lo es el nombre del directorio. Puede combinar estos para obtener el archivo de bus. Para dirname=001
y filname=001
, debería ser algo como / dev / bus / usb / 001/001.
Primero debe, aunque averiguar cuál es esta situación "usb.legacy". Estoy ejecutando la última versión y ni siquiera tengo un submódulo legacy
.
Finalmente, debe usar los campos idVendor
e idProduct
para identificar de forma única el dispositivo cuando está enchufado.
¿Cómo podemos consultar información de dispositivos USB conectados en Python? Quiero obtener el nombre del dispositivo UID (por ejemplo: SonyEricsson W660), ruta al dispositivo (por ejemplo: / dev / ttyACM0)
Y también, ¿cuál sería el mejor parámetro de la información anterior que se usará para identificar el dispositivo cada vez que se vuelva a conectar? (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 el resultado deseado, pegaré un ejemplo:
<usb.legacy.Device object at 0x1653990>
Device:
idVendor: 4046 (0x0fce)
idProduct: 53411 (0xd0a3)
Manufacturer: 1
Serial: 3
Product: 2
Primero no consigo el nombre de archivo, es lo más importante para mí. Supongo que es la parte / dev / ttyACM0, etc. En segundo lugar, supongo que hubo algún UID de cada dispositivo USB, ¿o debería usar la identificación del proveedor o del producto?
EDIT: Aparentemente tengo algunos problemas de configuración, creo que estoy usando la biblioteca USB incorrecta. (utilizando libusb0.1) ATM. Es por eso que obtengo la cadena Device (dev.filename) vacía. Si alguien puede por favor, simplemente díganle a qué sistema operativo está usando qué biblioteca USB y qué versión de PyUSB creo que resolverá mis problemas.
Para Linux, escribí un script llamado find_port.py que puede encontrar aquí: https://github.com/dhylands/usb-ser-mon/blob/master/usb_ser_mon/find_port.py
Utiliza pyudev para enumerar todos los dispositivos tty, y puede coincidir en varios atributos.
Use la opción --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. Utilice --help para ver las opciones de filtrado.
find_port.py imprime el nombre / dev / ttyXXX en lugar del nombre / dev / usb / ....
Para un sistema con usb heredado que regresa y libusb-1.0, este enfoque funcionará para recuperar las diversas cadenas reales. Muestro el vendedor 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 hagan arrojará 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
Puedes probar los enlaces de libusb
Puedo pensar en un código rápido como este.
Ya que se puede acceder a todos los puertos USB a través de / dev / bus / usb / <bus> / <device>
Para la ID generada, incluso si desenchufa 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''}
]
Si solo necesitas el nombre del dispositivo aquí hay un pequeño truco que escribí en bash. Para ejecutarlo en python necesitas el siguiente fragmento de código. 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. Simplemente guárdelo como un script de bash como foo.sh lo hace ejecutable.
#!/bin/bash
myvar=$(lsusb | grep "Bus $1 Device $2" | sed ''s//// /'' | awk ''{for(i=7;i<=NF;++i)print $i}'')
echo $myvar
Entonces llámalo en script python como
import os
os.system(''foo.sh'')