2013-04-11 67 views
2

我正在使用偉大的「evdev」庫來聆聽USB條形碼讀取器輸入,並且我需要檢測設備是否突然拔下/無響應,否則讀取循環的python腳本會變爲100在單個線程上使用%cpu,並慢慢地開始佔用所有可用的內存,導致整個系統在一段時間後崩潰。Python evdev檢測到設備已拔出

這個想法是檢測何時該設備被拔出並殺死當前腳本,導致主管嘗試重新啓動它,直到設備插回/變爲響應。

我使用讀取輸入的代碼如下:

devices = map(InputDevice, list_devices()) 

keys = { 
    2: 1, 
    3: 2, 
    4: 3, 
    5: 4, 
    6: 5, 
    7: 6, 
    8: 7, 
    9: 8, 
    10: 9, 
    11: 0, 
} 
dev = None 
for d in devices: 
    if d.name == 'Symbol Technologies, Inc, 2008 Symbol Bar Code Scanner': 
     print('%-20s %-32s %s' % (d.fn, d.name, d.phys)) 
     dev = InputDevice(d.fn) 
     break 

if dev is not None: 
    code = [] 
    for event in dev.read_loop(): 
     if event.type == ecodes.EV_KEY: 
      if event.value == 00: 
       if event.code != 96: 
        try: 
         code.append(keys[event.code]) 
        except: 
         code.append('-') 
       else: 
        card = "".join(map(str, code)) 
        print card 

        code = [] 
        card = "" 

所以,我怎麼會去這個做的正確方法?
一種方式我雖然可能會工作將是第二個腳本從cron運行每隔1到5分鐘,檢查是否所述設備仍然可用,如果它是現在,從某個文件中獲取進程ID並殺死該進程的方式,但這種方法的問題是,如果設備被拔出然後插回到檢查之間,「檢查器」腳本認爲一切正常,而主腳本緩慢崩潰 - 在「拔出」後不會重新激活

回答

5

python-evdev作者在這裏。知道自己的工作對別人有用,這是一種很好的感覺。謝謝你!

你一定要看看linux的設備管理器 - udev。無論何時添加或刪除設備,Linux內核都會發出事件。要在Python程序中監聽這些事件,可以使用pyudev,這是一個極好的基於ctypes的libudev綁定(請參見monitoring部分)。

下面是使用evdevpyudev一起的例子:

import functools 
import pyudev 

from evdev import InputDevice 
from select import select 

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

fds = {monitor.fileno(): monitor} 
finalizers = [] 

while True: 
    r, w, x = select(fds, [], []) 

    if monitor.fileno() in r: 
     r.remove(monitor.fileno()) 

     for udev in iter(functools.partial(monitor.poll, 0), None): 
      # we're only interested in devices that have a device node 
      # (e.g. /dev/input/eventX) 
      if not udev.device_node: 
       break 

      # find the device we're interested in and add it to fds 
      for name in (i['NAME'] for i in udev.ancestors if 'NAME' in i): 
       # I used a virtual input device for this test - you 
       # should adapt this to your needs 
       if u'py-evdev-uinput' in name: 
        if udev.action == u'add': 
         print('Device added: %s' % udev) 
         fds[dev.fd] = InputDevice(udev.device_node) 
         break 
        if udev.action == u'remove': 
         print('Device removed: %s' % udev) 
         def helper(): 
          global fds 
          fds = {monitor.fileno(): monitor} 
         finalizers.append(helper) 
         break 

    for fd in r: 
     dev = fds[fd] 
     for event in dev.read(): 
      print(event) 

    for i in range(len(finalizers)): 
     finalizers.pop()() 
+1

你好格奧爾基,請你會仔細看看我的了evdev問題? https://stackoverflow.com/questions/47262144/python-3-headless-rasppi-locale-de-de-not-possible-for-python-evdev謝謝 – ddlab 2017-11-14 09:33:18