it-swarm.com.de

Einfache Möglichkeit, Informationen zu verbundenen USB-Geräten in Python abzufragen?

Wie können Informationen zu verbundenen USB-Geräten in Python abgefragt werden? Ich möchte den UID-Gerätenamen (z. B. SonyEricsson W660) und den Pfad zum Gerät (z. B./dev/ttyACM0) erhalten.

Und was wäre der beste Parameter aus den obigen Informationen, um das Gerät zu identifizieren, wenn es erneut angeschlossen wird? (UID?)

Ich arbeite an Ubuntu 11.04.

ATM Ich habe diesen Code (mit 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

Das Problem ist, dass ich die gewünschte Ausgabe nicht bekomme. Ein Beispiel wird eingefügt:

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

Zuerst bekomme ich keinen Dateinamen, das ist mir am wichtigsten. Ich gehe davon aus, dass es sich um den Teil/dev/ttyACM0 usw. handelt. Zweitens, ich denke, es gab eine UID von jedem USB-Gerät, oder sollte ich sowohl Hersteller als auch Produkt-ID verwenden?

EDIT: Offensichtlich habe ich einige Probleme mit der Einrichtung. Ich glaube, ich verwende eine falsche USB-Bibliothek. (mit libusb0.1) ATM. Deshalb bekomme ich die Zeichenfolge für Device (dev.filename) leer. Wenn jemand kann, sagen Sie mir bitte einfach, auf welchem ​​Betriebssystem er welche USB Library und welche Version von PyUSB verwendet. Ich denke, es wird meine Probleme lösen.

25
BlackDivine

Ich kann mir so einen schnellen Code vorstellen.

Da auf alle USB-Ports über/dev/bus/usb/<Bus>/<Gerät> zugegriffen werden kann

Bei der generierten ID können Sie das Gerät auch dann entfernen, wenn Sie das Gerät vom Computer trennen und erneut anschließen [dies könnte ein anderer Port sein]. Es wird dasselbe sein.

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

Beispielausgabe hier ist:

[
{'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'}
]
43
meson10

Wenn Sie unter Windows arbeiten, können Sie pywin32 verwenden.

Ich habe ein Beispiel gefunden hier :

import win32com.client

wmi = win32com.client.GetObject ("winmgmts:")
for usb in wmi.InstancesOf ("Win32_USBHub"):
    print usb.DeviceID
33
joaquin

Für Linux habe ich ein Skript namens find_port.py geschrieben, das Sie hier finden können: https://github.com/dhylands/usb-ser-mon/blob/master/usb_ser_mon/find_port.py

Es verwendet pyudev zur Auflistung aller tty-Geräte und kann mit verschiedenen Attributen übereinstimmen.

Verwenden Sie die Option --list, um alle bekannten seriellen USB-Anschlüsse und ihre Attribute anzuzeigen. Sie können nach VID, PID, Seriennummer oder Lieferantenname filtern. Verwenden Sie --help, um die Filteroptionen anzuzeigen.

find_port.py gibt den Namen/dev/ttyXXX aus und nicht den Namen/dev/usb/....

3
Dave Hylands
2
wRAR

Bei einem System mit älterem usb und libusb-1.0 werden mit diesem Ansatz die verschiedenen tatsächlichen Zeichenfolgen abgerufen. Ich zeige den Verkäufer und das Produkt als Beispiele. Dies kann einige E/A-Vorgänge verursachen, da die Informationen tatsächlich vom Gerät gelesen werden (zumindest beim ersten Mal.) Einige Geräte liefern diese Informationen nicht, sodass die Annahme, dass sie dies tun, in diesem Fall eine Ausnahme auslöst. das ist in Ordnung, also gehen wir vorbei.

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
2
fyngyrz

Wenn ich Ihren Code ausführte, erhalte ich zum Beispiel die folgende Ausgabe.

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

Bemerkenswert ist, dass a) ich usb.Device-Objekte habe, wohingegen Sie usb.legacy.Device-Objekte haben, und b) ich Gerätedateinamen habe. 

Jeder usb.Bus hat ein dirname-Feld und jeder usb.Device hat den Dateinamen. Wie Sie sehen können, ist der Dateiname etwas wie 001 und auch der Verzeichnisname. Sie können diese kombinieren, um die Busdatei zu erhalten. Für dirname=001 und filname=001 sollte es etwas wie/dev/bus/usb/001/001 sein.

Sie sollten zuerst herausfinden, was diese "usb.legacy" -Situation ist. Ich verwende die neueste Version und habe nicht einmal ein Submodul legacy

Schließlich sollten Sie die Felder idVendor und idProduct verwenden, um das Gerät eindeutig zu identifizieren, wenn es angeschlossen ist.

1
user626998

Wenn Sie nur den Namen des Geräts benötigen, ist hier ein kleiner Hack, den ich in bash geschrieben habe. Um es in Python auszuführen, benötigen Sie den folgenden Ausschnitt. Ersetzen Sie einfach $ 1 und $ 2 durch Busnummer und Gerätenummer, z. B. 001 oder 002.

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

Alternativ können Sie es als Bash-Skript speichern und auch von dort aus ausführen. Speichern Sie es einfach als Bash-Skript wie foo.sh, um es ausführbar zu machen. 

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

Dann rufen Sie es in Python-Skript als auf 

import os
os.system('foo.sh')
0