Search code examples
pythonpyusb

(PyUSB) detect the last/new plug USB


I have a function can list out all the computer connection with USB port.

I want to detect the last/new USB I just plug in, then print out it's txt file from last/new USB I just plug.

One way I come up is that the function can run time1, before I plug USB in. Then there are 10 devices. After I plug in, time2, there are 11 devices. So I can differentiate the last one.

I read through relate question, Trigger new plugged USB-HDD or USB-Stick device but still not sure how to do.

  • function can list out all the computer connection with USB port:
import usb.core
import usb.backend.libusb1

print('idVendor  idProduct  Manufacturer - Product')
print('----------------------------------------------------')



busses = usb.busses()
for bus in busses:
    for dev in bus.devices:
        if dev:
            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)
            print('%8d  %9d  %s - %s' % (dev.idVendor, dev.idProduct,
                                         str(xdev._manufacturer).strip(),
                                         str(xdev._product).strip()))


output of all USB:

idVendor      idProduct      Manufacturer     - Product
----------------------------------------------------
    1133      49271  Logitech - USB Optical Mouse
    1423      37728   - USB Reader    34148       4096  JetFlash - Mass Storage Device
    7531          2  Linux 5.15.0-48-generic xhci-hcd - xHCI Host Controller
    7531          3  Linux 5.15.0-48-generic xhci-hcd - xHCI Host Controller
    5117       2112  Generic - External
    7531          2  Linux 5.15.0-48-generic xhci-hcd - xHCI Host Controller
    7531          3  Linux 5.15.0-48-generic xhci-hcd - xHCI Host Controller

Solution

  • You can use a dictionary to keep track of found devices. Each device has its unique serial-id which can be used as key.

    Then repeat the scan several times (e.g. in a loop with some seconds delay). If a device is not yet registered in the dictionary with its serial-id, you know it was recently added.

    Example

    import time
    from usb.core import find
    from usb.util import get_string
    import usb.backend.libusb1
    
    
    def info_usb_device(dev):
        xdev = find(idVendor=dev.idVendor, idProduct=dev.idProduct)
        if xdev.bDeviceClass == 9:  # don't list HUBs, see [USB class-codes](https://www.usb.org/defined-class-codes)
            return
        if xdev._manufacturer is None:
            xdev._manufacturer = get_string(xdev, xdev.iManufacturer, langid=1033)
        if xdev._product is None:
            xdev._product = get_string(xdev, xdev.iProduct, langid=1033)
        device_info = '[%20s] %8d %9d %s - %s' % (xdev.serial_number, dev.idVendor, dev.idProduct,
                                     str(xdev._manufacturer).strip(),
                                     str(xdev._product).strip())
        return (xdev.serial_number, device_info)
    
    
    def add_usb_devices(device_dict):
        new_devices = []
        for bus in usb.busses():
            for dev in bus.devices:
                if dev is None:
                    continue
                serial_info = info_usb_device(dev)
                if serial_info is not None:
                    (serial, info) = serial_info
                    if serial not in device_dict:
                        new_devices.append(serial)
                        device_dict[serial] = info
        return new_devices
    
    
    if __name__ == "__main__":
        device_dict = {}
        print('%22s %8s %9s %s' % ('serial', 'idVendor', 'idProduct', 'Manufacturer - Product'))
        print('-'*22, '-'*8,  '-'*9, '-'*30)
        # first scan
        add_usb_devices(device_dict)
        for device_info in device_dict.values():
            print(device_info)
        # next scans
        for i in range(5):  # run 5 more scans 
            new_serials = add_usb_devices(device_dict)
            if len(new_serials) > 0:
               print('** (scan %d) FOUND NEW USB DEVICES/SERIALS: %s' % (i, new_serials))
               for serial in new_serials:
                   print(device_dict[serial])
            time.sleep(3)  # waiting 3 seconds before new scan
        print('Scans completed.')