【问题标题】:Python evdev detect device unpluggedPython evdev 检测设备已拔出
【发布时间】:2013-04-03 10:10:42
【问题描述】:

我正在使用出色的“evdev”库来侦听 USB 条形码阅读器输入,我需要检测设备是否突然拔出/无响应,否则读取循环的 python 脚本会在 a 上达到 100% cpu 使用率单线程并慢慢开始吃掉所有可用内存,导致整个系统在一段时间后崩溃。

这个想法是检测设备何时被拔出并终止当前脚本,导致主管尝试重新启动它,直到设备重新插入/变得响应。

我用来读取输入的代码如下:

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 并以这种方式终止进程,但问题在于这种方法是,如果设备被拔掉,然后在检查之间插回,“检查器”脚本认为一切正常,而主脚本慢慢崩溃 - 在“拔出”后它不会重新激活

【问题讨论】:

    标签: python python-2.7 evdev


    【解决方案1】:

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    相关资源
    最近更新 更多