How to detect a new usb device is connected on python

35.7k views Asked by At

I want to make something which will run on the background and only after the computer detect new device is connected the rest of the code will run, is there any elegant way to do such a thing?

5

There are 5 answers

1
ralf htp On

this is operating system dependent

in linux you can use pyudev for this :

Almost the complete libudev functionality is exposed. You can:

  • Enumerate devices, filtered by specific criteria (pyudev.Context)
  • Query device information, properties and attributes,
  • Monitor devices, both synchronously and asynchronously with background threads, or within the event loops of Qt (pyudev.pyqt4, pyudev.pyside), glib (pyudev.glib) and wxPython (pyudev.wx).

https://pyudev.readthedocs.io/en/latest/

source code is in http://pyudev.readthedocs.io/en/v0.14/api/monitor.html, see the receive_device() function

in windows you can use the WMI ( Windows Management Instrumentation ) like in https://blogs.msdn.microsoft.com/powershell/2007/02/24/displaying-usb-devices-using-wmi/ ( Python Read the Device Manager Information ) or a python binding like in https://pypi.python.org/pypi/infi.devicemanager

0
djvg On

An alternative (also for windows) could be to use PySerial. You could use a QTimer (from PyQt) instead of the while-loop, either in a singlethreaded or multithreaded configuration. A basic example (without QTimer or threading):

import time
from serial.tools import list_ports  # pyserial

def enumerate_serial_devices():
    return set([item for item in list_ports.comports()])

def check_new_devices(old_devices):
    devices = enumerate_serial_devices()
    added = devices.difference(old_devices)
    removed = old_devices.difference(devices)
    if added:
        print 'added: {}'.format(added)
    if removed:
        print 'removed: {}'.format(removed)
    return devices

# Quick and dirty timing loop 
old_devices = enumerate_serial_devices()
while True:
    old_devices = check_new_devices(old_devices)
    time.sleep(0.5)
0
Orsiris de Jong On

you might use pyudev with something like

from pyudev import Context, Monitor

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

    for device in iter(monitor.poll, None):
        if device.action == 'add':
            print("Yay, we have a connected device")

I also developped a Python script that listens for specific devices and executes action when connected, eg:

pip install udev_monitor
udev_monitor.py --devices 0665:5161 --filters=usb --action /root/some_script.sh

You can find the full sources here

0
nonodu88 On

You can use WMIC for detecting usb if plugged

#coding:utf-8
import os

os.system("color")

Usb = os.popen("wmic logicaldisk where drivetype=2 get description ,deviceid ,volumename").read()
print(Usb)

if Usb.find("DeviceID") != -1:
    print("\033[1;32mUsb is plugged")
    input("")

else:
    print("\033[0;31mUsb is not plugged")
    input("")
2
Suave101 On

You can use the OS library to see all drives connected to your computer. The following code will tell you the drives name and if it was connected or disconnected. In addition the code executes the function foo() when a drive is connected. Also, when a drive is disconnected it will execute the command ham()

import os.path


def diff(list1, list2):
    list_difference = [item for item in list1 if item not in list2]
    return list_difference


def foo():
    print("New dive introduced")


def ham():
    print("Drive disconnected")


dl = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
drives = ['%s:' % d for d in dl if os.path.exists('%s:' % d)]
print(drives)
while True:
    uncheckeddrives = ['%s:' % d for d in dl if os.path.exists('%s:' % d)]
    x = diff(uncheckeddrives, drives)
    if x:
        print("New drives:     " + str(x))
        foo()
    x = diff(drives, uncheckeddrives)
    if x:
        print("Removed drives: " + str(x))
        ham()
    drives = ['%s:' % d for d in dl if os.path.exists('%s:' % d)]

This code is made for python 3.8 for windows