How to monitor usb devices insertion?
Question:
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?
Answers:
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()
You could use USBMonitor, which acts, in fact, as a wrapper of pyudev when you are running on Linux systems.
You should install it with
pip install usb-monitor
And then just trigger the monitor daemon, as you would do it with pyudev
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)
It should avoid you from some low-level problems like this, also avoiding, by the way, the OS dependency.
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?
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()
You could use USBMonitor, which acts, in fact, as a wrapper of pyudev when you are running on Linux systems.
You should install it with
pip install usb-monitor
And then just trigger the monitor daemon, as you would do it with pyudev
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)
It should avoid you from some low-level problems like this, also avoiding, by the way, the OS dependency.