Une façon Simple de demander des informations sur les périphériques USB connectés en Python?
Comment Pouvons-nous interroger les informations sur les périphériques USB connectés en Python? Je veux obtenir UID Nom de l'Appareil (ex: SonyEricsson W660), le chemin d'accès à l'appareil (ex: /dev/ttyACM0)
et aussi quel serait le meilleur paramètre parmi les informations ci-dessus pour être utilisé pour identifier l'appareil chaque fois qu'il est à nouveau connecté? (UID?)
je travaille sur Ubuntu 11.04.
ATM, j'ai ce code (à l'aide de 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
le problème est que je ne reçois pas la sortie désirée, va coller un exemple:
<usb.legacy.Device object at 0x1653990>
Device:
idVendor: 4046 (0x0fce)
idProduct: 53411 (0xd0a3)
Manufacturer: 1
Serial: 3
Product: 2
<!-D'abord, je n'ai pas de nom de fichier, c'est très important pour moi. Je suppose que c'est la partie /dev/ttyACM0 etc. Deuxièmement, je suppose qu'il y avait un peu D'UID de chaque périphérique USB, ou je devrais utiliser à la fois Vendeur ou id du produit?
EDIT: apparemment j'ai quelques problèmes de configuration, je pense que j'utilise la mauvaise Bibliothèque USB. (en utilisant libusb0.1) ATM. C'est pour ça que J'ai un appareil (dev.nom de fichier) chaîne vide. Si quelqu'un peut s'il vous plaît juste dire que sur le système d'exploitation qu'il utilise ce Bibliothèque USB et quelle version de PyUSB je pense qu'il va résoudre mes problèmes.
7 réponses
je peux penser à un code rapide comme celui-ci.
puisque tous les ports USB sont accessibles via / dev/bus/ usb / < bus > / < device >
pour L'ID généré, même si vous débranchez l'appareil et le rattachez de nouveau [ pourrait être un autre port ]. Ce sera la même chose.
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
Exemple de sortie sera ici:
[
{'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'}
]
quand j'exécute votre code, j'obtiens la sortie suivante par exemple.
<usb.Device object at 0xef38c0>
Device: 001
idVendor: 7531 (0x1d6b)
idProduct: 1 (0x0001)
Manufacturer: 3
Serial: 1
Product: 2
A noter que a) j'ai usb.Device
des objets, alors que vous avez usb.legacy.Device
les objets, et b) j'ai les noms de fichiers de l'appareil.
usb.Bus
a un dirname
et usb.Device
a le nom du fichier. Comme vous pouvez le voir, le nom du fichier est quelque chose comme 001
, et ainsi est le dirname. Vous pouvez les combiner pour obtenir le fichier bus. dirname=001
et filname=001
, ça devrait être quelque chose comme /dev/bus/usb/001/001.
vous devriez d'abord, mais comprendre ce que ce "usb.héritage" situation est. J'exécute la dernière version et je n'ai même pas un legacy
sous-module.
Enfin, vous devez utiliser le idVendor
et idProduct
champs pour identifier l'appareil lorsqu'il est branché.
pour un système avec RETOUR USB legacy et libusb-1.0, cette approche fonctionnera pour récupérer les différentes chaînes actuelles. Je montre le vendeur et le produit comme exemples. Il peut causer quelques E/S, parce qu'il lit réellement l'information de l'appareil (au moins la première fois, de toute façon.) Certains appareils ne fournissent pas cette information, de sorte que la présomption qu'ils le font va jeter une exception dans ce cas; c'est ok, donc nous passons.
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
pour linux, j'ai écrit un script appelé find_port.py que vous pouvez trouver ici: https://github.com/dhylands/usb-ser-mon/blob/master/find_port.py
il utilise pyudev pour énumérer tous les appareils tty, et peut correspondre à divers attributs.
utilisez l'option --list pour afficher tous les ports série USB connus et leurs attributs. Vous pouvez filtrer par VID, PID, numéro de série ou nom du vendeur. Utiliser l'option --help pour voir les options de filtrage.
find_port.py imprime le nom/dev /ttyXXX plutôt que le/dev/usb/... nom.
Si vous avez juste besoin du nom de l'appareil voici un petit hack qui je l'ai écrit en bash. Pour l'exécuter en python vous avez besoin de l'extrait suivant. Il suffit de remplacer 1 $et 2 $par le numéro de Bus et le numéro de périphérique eg 001 ou 002.
import os
os.system("lsusb | grep \"Bus Device \" | sed 's/\// /' | awk '{for(i=7;i<=NF;++i)print $i}'")
Alternativement, vous pouvez l'enregistrer comme un script bash et l'exécuter à partir de là aussi. Il suffit de le sauvegarder comme un script bash comme foo.sh le rendre exécutable.
#!/bin/bash
myvar=$(lsusb | grep "Bus Device " | sed 's/\// /' | awk '{for(i=7;i<=NF;++i)print $i}')
echo $myvar
alors l'appeler en script python comme
import os
os.system('foo.sh')