web-dev-qa-db-ja.com

Pythonで接続されたUSBデバイス情報を照会する簡単な方法は?

Pythonで接続されたUSBデバイス情報を照会するにはどうすればよいですか? UIDデバイス名(例:SonyEricsson W660)、デバイスへのパス(例:/ dev/ttyACM0)を取得したい

また、デバイスが再び接続されるたびにデバイスを識別するために使用される上記の情報の中で最適なパラメーターは何ですか? (UID?)

Ubuntu 11.04に取り組んでいます。

ATMこのコードを持っています(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

問題は、必要な出力が得られないことです。1つの例を貼り付けます。

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

最初にファイル名を取得しません、それは私にとって最も重要です。私はそれが/ dev/ttyACM0などの部分であると仮定しています。次に、すべてのUSBデバイスのUIDがあったと思いますか、それともベンダーIDと製品IDの両方を使用する必要がありますか?

編集:どうやらセットアップに問題があるようです。間違ったUSBライブラリを使用していると思います。(libusb0.1を使用して)ATM。彼はどのオペレーティングシステムでどのUSBライブラリとどのバージョンのPyUSBを使用しているかで問題を解決できると思います。

27
BlackDivine

このような簡単なコードを考えることができます。

/ dev/bus/usb/<バス>/<デバイス>を介してすべてのUSBポートにアクセスできるため

生成されたIDについては、デバイスを取り外して再接続しても[他のポートである可能性があります]。同じになります。

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

サンプル出力は次のとおりです。

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

Windowsで作業している場合は、 pywin32

例が見つかりました here

import win32com.client

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

Linuxの場合、find_port.pyというスクリプトを作成しました。このスクリプトは次の場所にあります。 https://github.com/dhylands/usb-ser-mon/blob/master/usb_ser_mon/find_port.py

Pyudevを使用してすべてのttyデバイスを列挙し、さまざまな属性で一致させることができます。

--listオプションを使用して、既知のUSBシリアルポートとその属性をすべて表示します。 VID、PID、シリアル番号、またはベンダー名でフィルタリングできます。 --helpを使用して、フィルタリングオプションを表示します。

find_port.pyは、/ dev/usb/...名ではなく、/ dev/ttyXXX名を出力します。

3
Dave Hylands

libusb bindings を試すことができます

2
wRAR

レガシーusbが戻ってきてlibusb-1.0を搭載したシステムの場合、このアプローチはさまざまな実際の文字列を取得するために機能します。例としてベンダーと製品を示します。実際にデバイスから情報を読み取るため、何らかのI/Oが発生する可能性があります(とにかく少なくとも最初は)。一部のデバイスはこの情報を提供しないので、その場合は例外がスローされます。大丈夫ですので合格です。

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

コードを実行すると、たとえば次の出力が表示されます。

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

注目すべきは、a)usb.Deviceオブジェクトがあるのに対し、usb.legacy.Deviceオブジェクトがあること、およびb)デバイスのファイル名があることです。

usb.Busにはdirnameフィールドがあり、各usb.Deviceにはファイル名があります。ご覧のとおり、ファイル名は001のようなもので、dirnameも同様です。これらを組み合わせて、バスファイルを取得できます。 dirname=001およびfilname=001の場合、/ dev/bus/usb/001/001のようなものでなければなりません。

最初に、この「usb.legacy」状況が何であるかを把握する必要があります。最新バージョンを実行していますが、legacyサブモジュールもありません。

最後に、idVendorおよびidProductフィールドを使用して、デバイスが接続されたときにデバイスを一意に識別する必要があります。

1
user626998

ここでデバイスの名前が必要な場合は、bashで書いた小さなハックです。 pythonで実行するには、次のスニペットが必要です。$ 1と$ 2をバス番号とデバイス番号、たとえば001または002に置き換えるだけです。

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

または、bashスクリプトとして保存し、そこから実行することもできます。 foo.shのようなbashスクリプトとして保存して、実行可能にします。

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

次に、pythonスクリプトとして

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