62 lines
1.5 KiB
Python
62 lines
1.5 KiB
Python
from dataclasses import dataclass
|
|
import pyudev
|
|
|
|
@dataclass
|
|
class USBDevice:
|
|
vendor_id: str | None
|
|
product_id: str | None
|
|
vendor: str | None
|
|
product: str | None
|
|
serial: str | None
|
|
|
|
@property
|
|
def id(self) -> str | None:
|
|
if self.vendor_id is None or self.product_id is None:
|
|
return None
|
|
|
|
return f"{self.vendor_id}:{self.product_id}"
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return f"{self.vendor} {self.product}"
|
|
|
|
class USBDevices:
|
|
def __init__(self):
|
|
self.context = pyudev.Context()
|
|
|
|
def enumerate(self) -> list[USBDevice]:
|
|
devices = []
|
|
|
|
for device in self.context.list_devices(
|
|
subsystem="usb",
|
|
DEVTYPE="usb_device"
|
|
):
|
|
usb_device = USBDevice(
|
|
vendor_id=device.get("ID_VENDOR_ID"),
|
|
product_id=device.get("ID_MODEL_ID"),
|
|
vendor=device.get("ID_VENDOR"),
|
|
product=device.get("ID_MODEL"),
|
|
serial=device.get("ID_SERIAL_SHORT"),
|
|
)
|
|
|
|
if self._is_valid_device(usb_device):
|
|
devices.append(usb_device)
|
|
|
|
return devices
|
|
|
|
@staticmethod
|
|
def _is_valid_device(device: USBDevice) -> bool:
|
|
# Exclude Linux USB root hubs
|
|
if device.vendor_id == "1d6b":
|
|
return False
|
|
|
|
return True
|
|
|
|
if __name__ == "__main__":
|
|
devices = USBDevices()
|
|
enumerated = devices.enumerate()
|
|
#print(devices.enumerate())
|
|
|
|
for device in enumerated:
|
|
print(device.id, device.name)
|