Как обнаружить новое USB-устройство подключено на Python

Я хочу сделать что-то, что будет работать в фоновом режиме, и только после того, как компьютер обнаружит, что новое устройство подключено, остальная часть кода будет запущена, есть ли какой-нибудь элегантный способ сделать это?

5 ответов

Это зависит от операционной системы

в Linux вы можете использовать pyudev за это:

Почти полная функциональность libudev. Вы можете:

  • Перечислять устройства, отфильтрованные по определенным критериям (pyudev.Context)
  • Запрос информации об устройстве, свойства и атрибуты,
  • Мониторинг устройств, как синхронно, так и асинхронно с фоновыми потоками, или в циклах событий Qt (pyudev.pyqt4, pyudev.pyside), glib (pyudev.glib) и wxPython (pyudev.wx).

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

исходный код находится в http://pyudev.readthedocs.io/en/v0.14/api/monitor.html, см. receive_device() функция

в окнах вы можете использовать WMI (инструментарий управления Windows), как в https://blogs.msdn.microsoft.com/powershell/2007/02/24/displaying-usb-devices-using-wmi/ ( Python Read the Device Manager Информация) или привязка Python, как в https://pypi.python.org/pypi/infi.devicemanager

Альтернативой (также для окон) может быть использование PySerial. Вы могли бы использовать QTimer (из PyQt) вместо while-loop, в однопоточной или многопоточной конфигурации. Базовый пример (без QTimer или нить)

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)

вы могли бы использоватьpyudevс чем-то вроде

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

Я также разработал скрипт Python, который прослушивает определенные устройства и выполняет действия при подключении, например:

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

Вы можете найти полные исходники здесь

Вы можете использовать WMIC для обнаружения usb, если он подключен

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

Вы можете использовать библиотеку ОС, чтобы увидеть все диски, подключенные к вашему компьютеру. Следующий код сообщит вам имя диска и будет ли он подключен или отключен. Кроме того, код выполняет функцию foo() при подключении диска. Также, когда диск отключен, он выполнит команду 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)]

Этот код сделан для python 3.8 для windows

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