在Python中查询连接的USB设备信息的简单方法?

发布于 2024-12-15 15:33:47 字数 1068 浏览 7 评论 0原文

如何在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

问题是我没有得到所需的输出,将粘贴一个示例:

<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。这就是为什么我的 Device (dev.filename) 字符串为空。如果有人可以告诉他在什么操作系统上使用什么 USB 库和什么版本的 PyUSB,我认为这会解决我的问题。

How can we query connected USB devices info in Python?
I want to get UID Device Name (ex: SonyEricsson W660), path to device (ex: /dev/ttyACM0)

And also what would be the best Parameter out of above info to be used as identifying the device whenever it's connected again? (UID?)

I am working on Ubuntu 11.04.

ATM I have this code (using 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

The problem is I don't get desired output, will paste one example:

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

First I don't get filename, it's most important to me. I am assuming it is the /dev/ttyACM0 etc part. Second, I guess there was some UID of every USB device, or I should use both Vendor or Product id?


Apparently I have some setup issues, I think I am using wrong USB Library. (using libusb0.1) ATM. That's why I get Device (dev.filename) string empty. If someone can please just tell that on what operating system he is using what USB Library and what version of PyUSB I think it will solve my problems.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

眼中杀气 2024-12-22 15:33:47

我可以想到这样的快速代码。

由于所有 USB 端口都可以通过 /dev/bus/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'}
]

Code Updated for Python 3

import re
import subprocess
device_re = re.compile(b"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(b'\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)

I can think of a quick code like this.

Since all USB ports can be accessed via /dev/bus/usb/< bus >/< device >

For the ID generated, even if you unplug the device and reattach it [ could be some other port ]. It will be the same.

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>.+)
quot;, 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

Sample output here will be:

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

Code Updated for Python 3

import re
import subprocess
device_re = re.compile(b"Bus\s+(?P<bus>\d+)\s+Device\s+(?P<device>\d+).+ID\s(?P<id>\w+:\w+)\s(?P<tag>.+)
quot;, re.I)
df = subprocess.check_output("lsusb")
devices = []
for i in df.split(b'\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)
一枫情书 2024-12-22 15:33:47

如果您在 Windows 上工作,可以使用 pywin32 (旧链接:请参阅下面的更新)。

我在这里找到了一个示例

import win32com.client

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

2020 年 4 月更新:

218 及更高版本的“pywin32”发行版本可以在 github 的此处找到。当前版本 227。

If you are working on windows, you can use pywin32 (old link: see update below).

I found an example here:

import win32com.client

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

Update Apr 2020:

'pywin32' release versions from 218 and up can be found here at github. Current version 227.

唱一曲作罢 2024-12-22 15:33:47

对于旧版 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

For a system with legacy usb coming back and libusb-1.0, this approach will work to retrieve the various actual strings. I show the vendor and product as examples. It can cause some I/O, because it actually reads the info from the device (at least the first time, anyway.) Some devices don't provide this information, so the presumption that they do will throw an exception in that case; that's ok, so we pass.

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
梦晓ヶ微光ヅ倾城 2024-12-22 15:33:47

对于 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/ttyXXX 名称而不是 /dev/usb/... 名称。

For linux, I wrote a script called find_port.py which you can find here:
https://github.com/dhylands/usb-ser-mon/blob/master/usb_ser_mon/find_port.py

It uses pyudev to enumerate all tty devices, and can match on various attributes.

Use the --list option to show all of the know USB serial ports and their attributes. You can filter by VID, PID, serial number, or vendor name. Use --help to see the filtering options.

find_port.py prints the /dev/ttyXXX name rather than the /dev/usb/... name.

不离久伴 2024-12-22 15:33:47

如果你只需要设备的名称,这里有一个我在 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 脚本并从那里运行它。只需将其保存为 bash 脚本(例如 foo.sh)即可使其可执行。

#!/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')

If you just need the name of the device here is a little hack which i wrote in bash. To run it in python you need the following snippet. Just replace $1 and $2 with Bus number and Device number eg 001 or 002.

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

Alternately you can save it as a bash script and run it from there too. Just save it as a bash script like foo.sh make it executable.

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

Then call it in python script as

import os
os.system('foo.sh')
衣神在巴黎 2024-12-22 15:33:47

例如,当我运行您的代码时,我会得到以下输出。

<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=001filname=001,它应该类似于 /dev/bus/usb/001/001。

不过,您应该首先弄清楚这个“usb.legacy”情况是什么。我正在运行最新版本,但我什至没有 legacy 子模块。

最后,您应该在插入设备时使用 idVendoridProduct 字段来唯一标识设备。

When I run your code, I get the following output for example.

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

Noteworthy are that a) I have usb.Device objects whereas you have usb.legacy.Device objects, and b) I have device filenames.

Each usb.Bus has a dirname field and each usb.Device has the filename. As you can see, the filename is something like 001, and so is the dirname. You can combine these to get the bus file. For dirname=001 and filname=001, it should be something like /dev/bus/usb/001/001.

You should first, though figure out what this "usb.legacy" situation is. I'm running the latest version and I don't even have a legacy sub-module.

Finally, you should use the idVendor and idProduct fields to uniquely identify the device when it's plugged in.

默嘫て 2024-12-22 15:33:47

对于linux系统,这里对原始海报代码进行了轻微修改,与python 3一起工作并解决了字节和字符串之间的转换。

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 = str(subprocess.check_output("lsusb"), 'utf-8')
print(df)
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)

此代码的输出示例:

[
{'id': '1d6b:0003', 'tag': 'Linux Foundation 3.0 root hub', 'device': '/dev/bus/usb/002/001'}, 
{'id': '0403:6011', 'tag': 'Future Technology Devices International, Ltd FT4232H Quad HS USB-UART/FIFO IC', 'device': '/dev/bus/usb/001/006'}, 
{'id': '1cbe:0003', 'tag': 'Luminary Micro Inc. Micro API', 'device': '/dev/bus/usb/001/018'}
]

For linux systems, here is a slight modification to the original posters code that works with python 3 and resolves the conversion between bytes and strings.

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>.+)
quot;, re.I)
df = str(subprocess.check_output("lsusb"), 'utf-8')
print(df)
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)

Example output from this code:

[
{'id': '1d6b:0003', 'tag': 'Linux Foundation 3.0 root hub', 'device': '/dev/bus/usb/002/001'}, 
{'id': '0403:6011', 'tag': 'Future Technology Devices International, Ltd FT4232H Quad HS USB-UART/FIFO IC', 'device': '/dev/bus/usb/001/006'}, 
{'id': '1cbe:0003', 'tag': 'Luminary Micro Inc. Micro API', 'device': '/dev/bus/usb/001/018'}
]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文