def find_descriptor(desc, find_all=False, custom_match=None, **args): r"""Find an inner descriptor. find_descriptor works in the same way as the core.find() function does, but it acts on general descriptor objects. For example, suppose you have a Device object called dev and want a Configuration of this object with its bConfigurationValue equals to 1, the code would be like so: >>> cfg = util.find_descriptor(dev, bConfigurationValue=1) You can use any field of the Descriptor as a match criteria, and you can supply a customized match just like core.find() does. The find_descriptor function also accepts the find_all parameter to get an iterator instead of just one descriptor. """ def desc_iter(**kwargs): for d in desc: tests = (val == getattr(d, key) for key, val in kwargs.items()) if _interop._all(tests) and (custom_match is None or custom_match(d)): yield d if find_all: return desc_iter(**args) else: try: return _interop._next(desc_iter(**args)) except StopIteration: return None
def find_descriptor(desc, find_all=False, custom_match=None, **args): r"""Find an inner descriptor. find_descriptor works in the same way the core.find() function does, but it acts on general descriptor objects. For example, suppose you have a Device object called dev and want a Configuration of this object with its bConfigurationValue equals to 1, the code would be like so: >>> cfg = util.find_descriptor(dev, bConfigurationValue=1) You can use any field of the Descriptor as a match criteria, and you can supply a customized match just like core.find() does. The find_descriptor function also accepts the find_all parameter to get a list of descriptor instead of just one. """ def desc_iter(k, v): for d in desc: if (custom_match is None or custom_match(d)) and _interop._reduce( lambda a, b: a and b, map(operator.eq, v, map(lambda i: getattr(d, i), k)), True ): yield d k, v = args.keys(), args.values() if find_all: return [d for d in desc_iter(k, v)] else: try: return _interop._next(desc_iter(k, v)) except StopIteration: return None
def find_descriptor(desc, find_all=False, custom_match=None, **args): r"""Find an inner descriptor. find_descriptor works in the same way as the core.find() function does, but it acts on general descriptor objects. For example, suppose you have a Device object called dev and want a Configuration of this object with its bConfigurationValue equals to 1, the code would be like so: >>> cfg = util.find_descriptor(dev, bConfigurationValue=1) You can use any field of the Descriptor as a match criteria, and you can supply a customized match just like core.find() does. The find_descriptor function also accepts the find_all parameter to get an iterator instead of just one descriptor. """ def desc_iter(k, v): for d in desc: if (custom_match is None or custom_match(d)) and \ _interop._reduce( lambda a, b: a and b, map( operator.eq, v, map(lambda i: getattr(d, i), k) ), True ): yield d k, v = args.keys(), args.values() if find_all: return desc_iter(k, v) else: try: return _interop._next(desc_iter(k, v)) except StopIteration: return None
def find(find_all=False, backend=None, custom_match=None, **args): r"""Find an USB device and return it. find() is the function used to discover USB devices. You can pass as arguments any combination of the USB Device Descriptor fields to match a device. For example: find(idVendor=0x3f4, idProduct=0x2009) will return the Device object for the device with idVendor field equals to 0x3f4 and idProduct equals to 0x2009. If there is more than one device which matchs the criteria, the first one found will be returned. If a matching device cannot be found the function returns None. If you want to get all devices, you can set the parameter find_all to True, then find will return an iterator with all matched devices. If no matching device is found, it will return an empty iterator. Example: for printer in find(find_all=True, bDeviceClass=7): print (printer) This call will get all the USB printers connected to the system. (actually may be not, because some devices put their class information in the Interface Descriptor). You can also use a customized match criteria: dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009) A more accurate printer finder using a customized match would be like so: def is_printer(dev): import usb.util if dev.bDeviceClass == 7: return True for cfg in dev: if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None: return True for printer in find(find_all=True, custom_match = is_printer): print (printer) Now even if the device class code is in the interface descriptor the printer will be found. You can combine a customized match with device descriptor fields. In this case, the fields must match and the custom_match must return True. In the our previous example, if we would like to get all printers belonging to the manufacturer 0x3f4, the code would be like so: printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer)) If you want to use find as a 'list all devices' function, just call it with find_all = True: devices = list(find(find_all=True)) Finally, you can pass a custom backend to the find function: find(backend = MyBackend()) PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB. If you do not supply a backend explicitly, find() function will select one of the predefineds backends according to system availability. Backends are explained in the usb.backend module. """ def device_iter(k, v): for dev in backend.enumerate_devices(): d = Device(dev, backend) if _interop._reduce( lambda a, b: a and b, map(operator.eq, v, map(lambda i: getattr(d, i), k)), True) and (custom_match is None or custom_match(d)): yield d if backend is None: import usb.backend.libusb1 as libusb1 import usb.backend.libusb0 as libusb0 import usb.backend.openusb as openusb for m in (libusb1, openusb, libusb0): backend = m.get_backend() if backend is not None: _logger.info('find(): using backend "%s"', m.__name__) break else: raise ValueError('No backend available') k, v = args.keys(), args.values() if find_all: return device_iter(k, v) else: try: return _interop._next(device_iter(k, v)) except StopIteration: return None
def find(find_all=False, backend = None, custom_match = None, **args): r"""Find an USB device and return it. find() is the function used to discover USB devices. You can pass as arguments any combination of the USB Device Descriptor fields to match a device. For example: find(idVendor=0x3f4, idProduct=0x2009) will return the Device object for the device with idVendor Device descriptor field equals to 0x3f4 and idProduct equals to 0x2009. If there is more than one device which matchs the criteria, the first one found will be returned. If a matching device cannot be found the function returns None. If you want to get all devices, you can set the parameter find_all to True, then find will return an list with all matched devices. If no matching device is found, it will return an empty list. Example: printers = find(find_all=True, bDeviceClass=7) This call will get all the USB printers connected to the system. (actually may be not, because some devices put their class information in the Interface Descriptor). You can also use a customized match criteria: dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009) A more accurate printer finder using a customized match would be like so: def is_printer(dev): import usb.util if dev.bDeviceClass == 7: return True for cfg in dev: if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None: return True printers = find(find_all=True, custom_match = is_printer) Now even if the device class code is in the interface descriptor the printer will be found. You can combine a customized match with device descriptor fields. In this case, the fields must match and the custom_match must return True. In the our previous example, if we would like to get all printers belonging to the manufacturer 0x3f4, the code would be like so: printers = find(find_all=True, idVendor=0x3f4, custom_match=is_printer) If you want to use find as a 'list all devices' function, just call it with find_all = True: devices = find(find_all=True) Finally, you may pass a custom backend to the find function: find(backend = MyBackend()) PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB. If you do not supply a backend explicitly, find() function will select one of the predefineds backends according to system availability. Backends are explained in the usb.backend module. """ def device_iter(k, v): for dev in backend.enumerate_devices(): d = Device(dev, backend) if _interop._reduce( lambda a, b: a and b, map( operator.eq, v, map(lambda i: getattr(d, i), k) ), True ) and (custom_match is None or custom_match(d)): yield d if backend is None: import usb.backend.libusb1 as libusb1 import usb.backend.libusb0 as libusb0 import usb.backend.openusb as openusb for m in (libusb1, openusb, libusb0): backend = m.get_backend() if backend is not None: _logger.info('find(): using backend "%s"', m.__name__) break else: raise ValueError('No backend available') k, v = args.keys(), args.values() if find_all: return [d for d in device_iter(k, v)] else: try: return _interop._next(device_iter(k, v)) except StopIteration: return None