2013-04-11 3 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 = "" 

그래서 어떻게이 적절한 방법을하고 가겠어요?
그 방법은 가능 할지도 모르지만 그 장치가 여전히 사용 가능한지 확인하는 매 1-5 분마다 cron에서 실행되는 두 번째 스크립트가 될 것입니다. 지금은 일부 파일의 프로세스 ID를 가져 와서 프로세스를 종료하지만 이 방법의 문제점은 장치가 연결 해제 된 후 검사 사이에 다시 연결되면 "검사기"스크립트는 주 스크립트가 천천히 충돌하는 동안 모든 것이 정상이라고 생각합니다. "연결 해제"후에 다시 활성화되지 않습니다.

답변

5

python-evdev 여기에 작성자. 자신의 작품이 다른 사람에게 유용하다는 것을 아는 것은 큰 기분입니다. 고마워요!

반드시 Linux의 장치 관리자 인 udev를 조사해야합니다. 리눅스 커널은 장치가 추가되거나 제거 될 때마다 이벤트를 방출합니다. Python 프로그램에서 이러한 이벤트를 수신하려면 pyudev을 사용하면됩니다. 이는 libtype에 대한 우수한 ctypes 기반 바인딩입니다 (monitoring 섹션 참조).

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 질문에 대해 자세히 살펴 것하십시오 :

여기 pyudev와 함께 evdev를 사용하는 예입니다? https://stackoverflow.com/questions/47262144/python-3-headless-rasppi-locale-de-de-not-possible-for-python-evdev Thanks – ddlab