pythonlinuxusbdbuspyudev

How to monitor usb devices insertion?


I am trying to monitor for USB devices when they get plugged in. A couple of test scripts fail that I am pretty sure should have worked.

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))

^^Does nothing. No error, no output.

I try

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

output the following error:

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 blocks me on both Linux Mint and a Pi3

How do I monitor for USB devices in python3?


Solution

  • pyudev accesses the linux udevadm tool. with this device attach / detach events are monitored with udevadm monitor

    what happens if you invoke udevadm monitor with python subprocess call ?

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

    what happens if you use MonitorObserver from pyudev ?

    have you tried to invoke python ( script ) as root ?

    the following two variants are working for me without root and invoked as script with -i option :

    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()