As you know every time USB device is rebooted is devnum
is changed, but physical USB port is the same as was.
Sometimes it's needed to convert static USB path from lsub -t
to current device num on sysfs (/dev/bus/usb/XXX/YYY
). It's useful for working with devices often are rebooted.
Some little solution that I've found, this script just convert static USB path from lsusb -t
utility to current device on sysfs.
For example, you connected your device to your PC. And its physical topology, for example, is: 218
, where 2 is USB bus, and 18 is nested port hierarchy, it's hierarchy will change only if you change physical USB port on your PC.
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M
|__ Port 5: Dev 8, If 0, Class=Vendor Specific Class, Driver=ftdi_sio, 12M
|__ Port 6: Dev 4, If 0, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 8: Dev 6, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
And how to convert it:
def get_device_path(target_path):
"""
Return current dynamic USB device path from static lsusb topology.
Example:
218 -> /dev/bus/usb/002/006
Where 2 is bus number and 18 is topology level of `lsusb` utility.
"""
root_dir = "/sys/bus/usb/devices"
target_bus = int(target_path[0])
for device in os.listdir(root_dir):
if "usb" in device:
continue
device_path = device.split(":")[0].replace(".", "") \
.replace("-", "")
if device_path != target_path:
continue
devnum_path = os.path.join(root_dir, device, "devnum")
if not os.path.exists(devnum_path):
continue
with open(devnum_path) as fh:
device_num = int(fh.read().strip())
return "/dev/bus/usb/{:03d}/{:03d}".format(target_bus, device_num)