Как контролировать вставку USB-устройств?

Я пытаюсь отслеживать USB-устройства, когда они подключены. Не удалось выполнить пару тестовых сценариев, которые, я уверен, должны сработать.

import pyudev

context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='usb')

for device in iter(monitor.poll, None):
    if device.action == 'add':
        print('{} connected'.format(device))

^^ Ничего не делает. Нет ошибок, нет выходных.

я попробую

import dbus
bus = dbus.SystemBus()
obj = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager')
obj.GetDevices()

выведите следующую ошибку:

Traceback (most recent call last):
  File "crap.py", line 4, in <module>
    obj.GetDevices()
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 70, in __call__
    return self._proxy_method(*args, **keywords)
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UnknownMethod: No such interface '(null)' on object at path /org/freedesktop/NetworkManager

dbus блокирует меня как на Linux Mint, так и на Pi3

Как мне следить за USB-устройствами в python3?

2 ответа

Решение

pyudev получает доступ к Linux udevadm инструмент. с этим устройством события присоединения / отсоединения отслеживаются с udevadm monitor

что произойдет, если вы вызываете udevadm monitor с вызовом подпроцесса python?

  from subprocess import call
  call(["udevadm","monitor"])

что произойдет, если вы используете MonitorObserver от пудева?

Вы пытались вызвать Python (скрипт) от имени root?

следующие два варианта работают для меня без рута и запускаются как скрипт с -i вариант:

from pyudev import Context, Monitor

context = Context()
monitor = Monitor.from_netlink(context)
device = monitor.poll(timeout=None)
if device:
    print('{0.action}: {0}'.format(device))

-

from pyudev import Context, Monitor, MonitorObserver

context = Context()
monitor = Monitor.from_netlink(context)
monitor.filter_by(subsystem='usb')
def print_device_event(device):
    print('background event {0.action}: {0.device_path}'.format(device))
observer = MonitorObserver(monitor, callback=print_device_event, name='monitor-observer')
observer.daemon
observer.start()

Вы можете использовать USBMonitor, который фактически действует как оболочка при работе в системах Linux.

Вы должны установить его с помощью

      pip install usb-monitor

А затем просто запустите демон монитора, как если бы вы сделали это с pyudevpyudev.

      from usbmonitor import USBMonitor

# Define the `on_connect` function
on_connect = lambda device_id, device_info: print('{} connected'.format(device_id))

# Create the Monitor instance
monitor = USBMonitor()

# Start the daemon
monitor.start_monitoring(on_connect=on_connect, on_disconnect=None)

Это должно избавить вас от некоторых подобных низкоуровневых проблем, а также, кстати, избежать зависимости от ОС.

Другие вопросы по тегам