Reputation: 5384
I am trying to find a way to iterate over all USB devices on a Raspberry Pi, and print out Vendor ID, Product ID, manufacturer name, and device node; via posts like:
... I understood I could use PyUSB - but I'm having lots of trouble, similar to:
... which that post does not answer.
So here is my test case - I have this on the Raspberry Pi Raspbian Stretch:
pi@raspberry:~ $ apt-show-versions -r libusb
libusb-0.1-4:armhf/stretch 2:0.1.12-30 uptodate
libusb-1.0-0:armhf/stretch 2:1.0.21-1 uptodate
libusbmuxd4:armhf/stretch 1.0.10-3 uptodate
I installed PyUSB with:
sudo pip3 install pyusb
As an example, I've connected an Arduino UNO to the Raspberry Pi; tail -f /var/log/syslog
prints this upon USB connection:
...
Jun 23 09:35:01 raspberry kernel: [71431.582554] usb 1-1.2: new full-speed USB device number 7 using dwc_otg
Jun 23 09:35:01 raspberry kernel: [71431.726403] usb 1-1.2: New USB device found, idVendor=2341, idProduct=0043, bcdDevice= 0.01
Jun 23 09:35:01 raspberry kernel: [71431.726420] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=220
Jun 23 09:35:01 raspberry kernel: [71431.726431] usb 1-1.2: Manufacturer: Arduino (www.arduino.cc)
Jun 23 09:35:01 raspberry kernel: [71431.726440] usb 1-1.2: SerialNumber: 64131383231351C03272
Jun 23 09:35:01 raspberry mtp-probe: checking bus 1, device 7: "/sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2"
Jun 23 09:35:01 raspberry mtp-probe: bus: 1, device: 7 was not an MTP device
Jun 23 09:35:01 raspberry kernel: [71431.778630] cdc_acm 1-1.2:1.0: ttyACM0: USB ACM device
Jun 23 09:35:01 raspberry kernel: [71431.779553] usbcore: registered new interface driver cdc_acm
Jun 23 09:35:01 raspberry kernel: [71431.779562] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
...
So, I know that Vendor ID is 0x2341 (apparently, hex), Product ID is 0x0043 (apparently, hex), manufacturer name is Arduino (www.arduino.cc)
, and device node/file is /dev/ttyACM0
; and I simply want to print this out for all USB devices that are connected to the system via PyUSB.
Now, there is a bit of confusion online, since apparently, you can iterate over USB devices in PyUSB in two ways: the old "legacy" way, and the "new" way/API. So, I made a test script which tries them both, which I call test-usb.py
:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import usb.core
import usb.util
print("This is 'old' PyUSB style iteration - uses legacy:")
busses = usb.busses() # SO:8110310
for bus in busses:
print(type(bus)) # <class 'usb.legacy.Bus'>
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 = "USB VID: 0x{:04X} PID: 0x{:04X} Mfr name '{}' Product '{}'".format(dev.idVendor, dev.idProduct, str(xdev._manufacturer).strip(), str(xdev._product).strip(), dev.filename)
print( stx )
try:
print("xdev.filename: '{}'".format(xdev.filename))
except Exception as e:
print("xdev.filename exception: {}".format(e))
try:
print("dev.filename: '{}'".format(dev.filename))
except Exception as e:
print("dev.filename exception: {}".format(e))
except Exception as e:
print("Exception: {}".format(e))
print()
def print_internals(dev): # SO: 18224189
for attrib in dir(dev):
if not attrib.startswith('_') and not attrib == 'configurations':
try:
x=getattr(dev, attrib)
print( " ", attrib, x)
except Exception as e:
print("Exception for attrib '{}': {}".format(attrib, e))
try:
for config in dev.configurations:
for attrib in dir(config):
if not attrib.startswith('_'):
try:
x=getattr(config, attrib)
print( " ", attrib, x)
except Exception as e:
print("Exception for attrib '{}': {}".format(attrib, e))
except Exception as e:
print("Exception config in dev.configurations: {}".format(e))
print("This is 'new' PyUSB style iteration - does not use legacy:")
for xdev in usb.core.find(find_all=True): # SO:9577601
print(type(xdev)) # <class 'usb.core.Device'>
try:
if xdev._manufacturer is None:
xdev._manufacturer = usb.util.get_string(xdev, xdev.iManufacturer)
except Exception as e:
print("Exception: {}".format(e))
try:
if xdev._product is None:
xdev._product = usb.util.get_string(xdev, xdev.iProduct)
except Exception as e:
print("Exception: {}".format(e))
stx = "USB VID: 0x{:04X} PID: 0x{:04X} Mfr name '{}' Product '{}'".format(xdev.idVendor, xdev.idProduct, str(xdev._manufacturer).strip(), str(xdev._product).strip())
print( stx )
try:
print("xdev.filename: '{}'".format(xdev.filename))
except Exception as e:
print("xdev.filename exception: {}".format(e))
print_internals(xdev)
The above script outputs:
pi@raspberry:~ $ python3 test-usb.py
This is 'old' PyUSB style iteration - uses legacy:
<class 'usb.legacy.Bus'>
Exception: The device has no langid
USB VID: 0x0424 PID: 0x7800 Mfr name 'None' Product 'None'
xdev.filename exception: 'Device' object has no attribute 'filename'
dev.filename: ''
USB VID: 0x0424 PID: 0x2514 Mfr name 'None' Product 'None'
xdev.filename exception: 'Device' object has no attribute 'filename'
dev.filename: ''
USB VID: 0x0424 PID: 0x2514 Mfr name 'None' Product 'None'
xdev.filename exception: 'Device' object has no attribute 'filename'
dev.filename: ''
Exception: The device has no langid
This is 'new' PyUSB style iteration - does not use legacy:
<class 'usb.core.Device'>
Exception: The device has no langid
Exception: The device has no langid
USB VID: 0x2341 PID: 0x0043 Mfr name 'None' Product 'None'
xdev.filename exception: 'Device' object has no attribute 'filename'
address 7
attach_kernel_driver <bound method Device.attach_kernel_driver of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
bDescriptorType 1
bDeviceClass 2
bDeviceProtocol 0
bDeviceSubClass 0
bLength 18
bMaxPacketSize0 8
bNumConfigurations 1
backend <usb.backend.libusb1._LibUSB object at 0x7680f510>
bcdDevice 1
bcdUSB 272
bus 1
clear_halt <bound method Device.clear_halt of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
ctrl_transfer <bound method Device.ctrl_transfer of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
default_timeout 1000
detach_kernel_driver <bound method Device.detach_kernel_driver of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
finalize <bound method AutoFinalizedObject.finalize of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
get_active_configuration <bound method Device.get_active_configuration of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
iManufacturer 1
iProduct 2
iSerialNumber 220
idProduct 67
idVendor 9025
is_kernel_driver_active <bound method Device.is_kernel_driver_active of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
langids ()
Exception for attrib 'manufacturer': The device has no langid
port_number 2
port_numbers (1, 2)
Exception for attrib 'product': The device has no langid
read <bound method Device.read of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
reset <bound method Device.reset of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
Exception for attrib 'serial_number': The device has no langid
set_configuration <bound method Device.set_configuration of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
set_interface_altsetting <bound method Device.set_interface_altsetting of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
speed 2
write <bound method Device.write of <DEVICE ID 2341:0043 on Bus 001 Address 007>>
Exception config in dev.configurations: 'method' object is not iterable
<class 'usb.core.Device'>
USB VID: 0x0424 PID: 0x7800 Mfr name 'None' Product 'None'
xdev.filename exception: 'Device' object has no attribute 'filename'
address 4
attach_kernel_driver <bound method Device.attach_kernel_driver of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
bDescriptorType 1
bDeviceClass 255
bDeviceProtocol 255
bDeviceSubClass 0
bLength 18
bMaxPacketSize0 64
bNumConfigurations 1
backend <usb.backend.libusb1._LibUSB object at 0x7680f510>
bcdDevice 768
bcdUSB 528
bus 1
clear_halt <bound method Device.clear_halt of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
ctrl_transfer <bound method Device.ctrl_transfer of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
default_timeout 1000
detach_kernel_driver <bound method Device.detach_kernel_driver of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
finalize <bound method AutoFinalizedObject.finalize of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
get_active_configuration <bound method Device.get_active_configuration of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
iManufacturer 0
iProduct 0
iSerialNumber 0
idProduct 30720
idVendor 1060
is_kernel_driver_active <bound method Device.is_kernel_driver_active of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
langids ()
manufacturer None
port_number 1
port_numbers (1, 1, 1)
product None
read <bound method Device.read of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
reset <bound method Device.reset of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
serial_number None
set_configuration <bound method Device.set_configuration of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
set_interface_altsetting <bound method Device.set_interface_altsetting of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
speed 3
write <bound method Device.write of <DEVICE ID 0424:7800 on Bus 001 Address 004>>
Exception config in dev.configurations: 'method' object is not iterable
<class 'usb.core.Device'>
USB VID: 0x0424 PID: 0x2514 Mfr name 'None' Product 'None'
xdev.filename exception: 'Device' object has no attribute 'filename'
address 3
attach_kernel_driver <bound method Device.attach_kernel_driver of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
bDescriptorType 1
bDeviceClass 9
bDeviceProtocol 2
bDeviceSubClass 0
bLength 18
bMaxPacketSize0 64
bNumConfigurations 1
backend <usb.backend.libusb1._LibUSB object at 0x7680f510>
bcdDevice 2995
bcdUSB 512
bus 1
clear_halt <bound method Device.clear_halt of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
ctrl_transfer <bound method Device.ctrl_transfer of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
default_timeout 1000
detach_kernel_driver <bound method Device.detach_kernel_driver of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
finalize <bound method AutoFinalizedObject.finalize of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
get_active_configuration <bound method Device.get_active_configuration of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
iManufacturer 0
iProduct 0
iSerialNumber 0
idProduct 9492
idVendor 1060
is_kernel_driver_active <bound method Device.is_kernel_driver_active of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
langids ()
manufacturer None
port_number 1
port_numbers (1, 1)
product None
read <bound method Device.read of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
reset <bound method Device.reset of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
serial_number None
set_configuration <bound method Device.set_configuration of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
set_interface_altsetting <bound method Device.set_interface_altsetting of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
speed 3
write <bound method Device.write of <DEVICE ID 0424:2514 on Bus 001 Address 003>>
Exception config in dev.configurations: 'method' object is not iterable
<class 'usb.core.Device'>
USB VID: 0x0424 PID: 0x2514 Mfr name 'None' Product 'None'
xdev.filename exception: 'Device' object has no attribute 'filename'
address 2
attach_kernel_driver <bound method Device.attach_kernel_driver of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
bDescriptorType 1
bDeviceClass 9
bDeviceProtocol 2
bDeviceSubClass 0
bLength 18
bMaxPacketSize0 64
bNumConfigurations 1
backend <usb.backend.libusb1._LibUSB object at 0x7680f510>
bcdDevice 2995
bcdUSB 512
bus 1
clear_halt <bound method Device.clear_halt of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
ctrl_transfer <bound method Device.ctrl_transfer of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
default_timeout 1000
detach_kernel_driver <bound method Device.detach_kernel_driver of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
finalize <bound method AutoFinalizedObject.finalize of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
get_active_configuration <bound method Device.get_active_configuration of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
iManufacturer 0
iProduct 0
iSerialNumber 0
idProduct 9492
idVendor 1060
is_kernel_driver_active <bound method Device.is_kernel_driver_active of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
langids ()
manufacturer None
port_number 1
port_numbers (1,)
product None
read <bound method Device.read of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
reset <bound method Device.reset of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
serial_number None
set_configuration <bound method Device.set_configuration of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
set_interface_altsetting <bound method Device.set_interface_altsetting of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
speed 3
write <bound method Device.write of <DEVICE ID 0424:2514 on Bus 001 Address 002>>
Exception config in dev.configurations: 'method' object is not iterable
<class 'usb.core.Device'>
Exception: The device has no langid
Exception: The device has no langid
USB VID: 0x1D6B PID: 0x0002 Mfr name 'None' Product 'None'
xdev.filename exception: 'Device' object has no attribute 'filename'
address 1
attach_kernel_driver <bound method Device.attach_kernel_driver of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
bDescriptorType 1
bDeviceClass 9
bDeviceProtocol 1
bDeviceSubClass 0
bLength 18
bMaxPacketSize0 64
bNumConfigurations 1
backend <usb.backend.libusb1._LibUSB object at 0x7680f510>
bcdDevice 1049
bcdUSB 512
bus 1
clear_halt <bound method Device.clear_halt of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
ctrl_transfer <bound method Device.ctrl_transfer of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
default_timeout 1000
detach_kernel_driver <bound method Device.detach_kernel_driver of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
finalize <bound method AutoFinalizedObject.finalize of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
get_active_configuration <bound method Device.get_active_configuration of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
iManufacturer 3
iProduct 2
iSerialNumber 1
idProduct 2
idVendor 7531
is_kernel_driver_active <bound method Device.is_kernel_driver_active of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
langids ()
Exception for attrib 'manufacturer': The device has no langid
port_number 0
port_numbers None
Exception for attrib 'product': The device has no langid
read <bound method Device.read of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
reset <bound method Device.reset of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
Exception for attrib 'serial_number': The device has no langid
set_configuration <bound method Device.set_configuration of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
set_interface_altsetting <bound method Device.set_interface_altsetting of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
speed 3
write <bound method Device.write of <DEVICE ID 1d6b:0002 on Bus 001 Address 001>>
Exception config in dev.configurations: 'method' object is not iterable
So, the only thing I could get to, is USB VID: 0x2341 PID: 0x0043; the exception The device has no langid
prevents retrieval of manufacturer and product name (and there are a ton of other exceptions, too)
And no one knows where the device node/path is: apparently, there used to be a dev.filename
in the "legacy" mode, which maybe at a certain point in the past, maybe did contain the device node/file /dev/ttyACM0
- but now seemingly does not anymore, as it is empty; and I couldn't find a mention of where that information resides in the "new" API (if it's there).
So - how can I iterate over all USB devices in Python 3 in Linux, and print out Vendor ID, Product ID, manufacturer name, and device node filename? If this is not possible with PyUSB - what other options do I have in terms of Python libraries (I'd like to avoid parsing /var/log/syslog
or /dev/bus
manually)?
Upvotes: 1
Views: 3357
Reputation: 5384
Ok, I think I got somewhere.
First, it is no longer possible to obtain device node (file) via PyUSB:
filename not work and not list all device attach with usb · Issue #165 · pyusb/pyusb · GitHub
Filenames are no longer supported: the legacy API returns empty strings (and libusb-compat fakes them with the address number).
Second, a device node like for the Arduino UNO only exists for a USB devices that expose a USB serial port (or in other words, for devices for which the OS loads a USB-serial kernel driver); a different USB class (I guess, like mass storage device), would probably not expose a similar device node.
Third, as far as the problem with "langid" goes:
ValueError: The device has no langid · Issue #139 · pyusb/pyusb · GitHub
However in some of the other comments it is a question of permissions: If you don't have permissions you cannot retrieve the langid nor the serial number/manufacturer/product strings.
...
The most common cause for
ValueError: The device has no langid
is simply lack of permission to access the device. Try running your program withsudo
and, if that works, consider using a udev rule to grant access to the device to the unprivileged users.
So, since I don't want to run my script as sudo
, and I don't want to write a udev rule - the only way to retrieve this info I found, was to use PyUSB to just iterate over VendorIDs and ProductIDs; then pass this over to pyudev
, from where we can find the device node, if it is a USB serial device - and in that case, we can also retrieve Manufacturer and Product strings.
Here is the script - again called test-usb.py
:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import usb.core # sudo pip3 install pyusb
import usb.util
import pyudev # sudo pip3 install pyudev
import inspect
pyudev_context = pyudev.Context() # SO:8110310 -> github.com/dhylands/usb-ser-mon (find_port.py)
#for device in pyudev_context.list_devices(subsystem='tty'):
# print( device.device_node )
# # note: device.properties['ID_VENDOR_ID'] is a string, hex representation of the ID number, without "0x" prefix
# try:
# print( type( device.properties['ID_VENDOR_ID'] ) )
# except Exception as e:
# print( e )
# try:
# print( device.properties['ID_MODEL_ID'] )
# except Exception as e:
# print( e )
for xdev in usb.core.find(find_all=True):
langids_str = ""
try:
langids_str = usb.util.get_langids(xdev)
except Exception as e:
langids_str = e
## trying to set _langids without sudo, will get rid of the 'ValueError: The device has no langid',
## however, mostly we'll just get '[Errno 13] Access denied (insufficient permissions)' instead
#if xdev._langids is None:
# xdev._langids = (1033,)
try:
mfr_str = usb.util.get_string(xdev, xdev.iManufacturer)
except Exception as e:
mfr_str = e
try:
prod_str = usb.util.get_string(xdev, xdev.iProduct)
except Exception as e:
prod_str = e
# check if it is USB serial device, with a device node/filename
devnode_str = "No device node"
vidhex_str = "{:04X}".format(xdev.idVendor)
pidhex_str = "{:04X}".format(xdev.idProduct)
for device in pyudev_context.list_devices(subsystem='tty'):
try:
if ( (vidhex_str.lower() == device.properties['ID_VENDOR_ID'].lower() ) and (pidhex_str.lower() == device.properties['ID_MODEL_ID'].lower()) ):
devnode_str = "{} ({} ; {})".format(device.device_node, device.properties['ID_VENDOR'], device.properties['ID_MODEL_FROM_DATABASE'] )
#for ikey in device.properties.keys(): print(ikey)
except:
pass
out_str = "VID: 0x{}, PID: 0x{}, devnode: {}, langids: '{}', Mfr: '{}', Prod: '{}'".format(
vidhex_str, pidhex_str, devnode_str, langids_str, mfr_str, prod_str
)
print(out_str)
## for ikey in device.properties.keys(): print(ikey):
# DEVLINKS
# DEVNAME
# DEVPATH
# ID_BUS
# ID_MODEL
# ID_MODEL_ENC
# ID_MODEL_FROM_DATABASE
# ID_MODEL_ID
# ID_PATH
# ID_PATH_TAG
# ID_REVISION
# ID_SERIAL
# ID_SERIAL_SHORT
# ID_TYPE
# ID_USB_CLASS_FROM_DATABASE
# ID_USB_DRIVER
# ID_USB_INTERFACES
# ID_USB_INTERFACE_NUM
# ID_VENDOR
# ID_VENDOR_ENC
# ID_VENDOR_FROM_DATABASE
# ID_VENDOR_ID
# MAJOR
# MINOR
# SUBSYSTEM
# TAGS
# USEC_INITIALIZED
Here is what the script outputs on a Raspberry Pi/Stretch with Arduino UNO connected - with sudo
:
pi@raspberry:~ $ sudo python3 test-usb.py
VID: 0x2341, PID: 0x0043, devnode: /dev/ttyACM0 (Arduino__www.arduino.cc_ ; Uno R3 (CDC ACM)), langids: '(1033,)', Mfr: 'Arduino (www.arduino.cc)', Prod: '[Errno 32] Pipe error'
VID: 0x0424, PID: 0x7800, devnode: No device node, langids: '[Errno 32] Pipe error', Mfr: 'None', Prod: 'None'
VID: 0x0424, PID: 0x2514, devnode: No device node, langids: '[Errno 32] Pipe error', Mfr: 'None', Prod: 'None'
VID: 0x0424, PID: 0x2514, devnode: No device node, langids: '[Errno 32] Pipe error', Mfr: 'None', Prod: 'None'
VID: 0x1D6B, PID: 0x0002, devnode: No device node, langids: '(1033,)', Mfr: 'Linux 4.19.66-v7+ dwc_otg_hcd', Prod: 'DWC OTG Controller'
Here is what it outputs without sudo
:
pi@raspberry:~ $ python3 test-usb.py
VID: 0x2341, PID: 0x0043, devnode: /dev/ttyACM0 (Arduino__www.arduino.cc_ ; Uno R3 (CDC ACM)), langids: '[Errno 13] Access denied (insufficient permissions)', Mfr: 'The device has no langid', Prod: 'The device has no langid'
VID: 0x0424, PID: 0x7800, devnode: No device node, langids: '[Errno 13] Access denied (insufficient permissions)', Mfr: 'None', Prod: 'None'
VID: 0x0424, PID: 0x2514, devnode: No device node, langids: '[Errno 13] Access denied (insufficient permissions)', Mfr: 'None', Prod: 'None'
VID: 0x0424, PID: 0x2514, devnode: No device node, langids: '[Errno 13] Access denied (insufficient permissions)', Mfr: 'None', Prod: 'None'
VID: 0x1D6B, PID: 0x0002, devnode: No device node, langids: '[Errno 13] Access denied (insufficient permissions)', Mfr: 'The device has no langid', Prod: 'The device has no langid'
Note that the Arduino Uno, seemingly, does not have a product string description exposed via USB - and correspondingly, in pyudev, device.properties['ID_MODEL']
for it prints just 0043
- but device.properties['ID_MODEL_FROM_DATABASE']
prints the actual model name.
Upvotes: 1