Simple way to query connected USB devices info in Python?

后端 未结 6 2129
独厮守ぢ
独厮守ぢ 2020-11-28 03:17

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 b

相关标签:
6条回答
  • 2020-11-28 03:41

    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')
    
    0 讨论(0)
  • 2020-11-28 03:46

    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.

    0 讨论(0)
  • 2020-11-28 03:52

    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
    
    0 讨论(0)
  • 2020-11-28 03:54

    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>.+)$", 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>.+)$", 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)
    
    0 讨论(0)
  • 2020-11-28 04:04

    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.

    0 讨论(0)
  • 2020-11-28 04:06

    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.

    0 讨论(0)
提交回复
热议问题