You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求Evdev针对USB条码扫描器短暂断连的错误修正方案

Zebra扫描器Evdev异常处理与自动设备映射方案

针对扫描器放回底座时短暂断开导致的报错问题,以下方案实现了自动设备识别、异常捕获和持续重试逻辑,同时替代了固定设备路径的写法:

1. 自动识别Zebra扫描器

不再指定固定的/dev/input/eventx路径,而是通过设备名称或硬件ID自动匹配Zebra扫描器:

  • 名称匹配:扫描器名称通常包含"Zebra"或"Symbol"关键字
  • 硬件ID匹配:通过lsusb命令获取设备的VID/PID(Zebra常见VID为0x05e0),匹配更精准

2. 核心错误处理逻辑

  • 捕获设备读取时的OSError异常,及时移除失效设备,避免程序崩溃
  • 给select设置超时,定时重新扫描设备,确保断开后重连的设备能被快速识别
  • 无设备时持续等待重试,不会退出程序

3. 完整代码实现

from evdev import InputDevice, list_devices
from select import select
import time

def find_zebra_scanners():
    """自动查找所有Zebra/Symbol条码扫描器"""
    scanners = []
    # 用lsusb命令查看你的扫描器VID/PID,替换以下值
    ZEBRA_VID = 0x05e0
    ZEBRA_PID = None  # 例如0x1400,留空则只匹配VID

    for path in list_devices():
        try:
            dev = InputDevice(path)
            # 名称匹配或硬件ID匹配,二选一或结合使用
            if ("Zebra" in dev.name or "Symbol" in dev.name) or \
               (dev.info.vendor == ZEBRA_VID and (ZEBRA_PID is None or dev.info.product == ZEBRA_PID)):
                scanners.append(dev)
        except OSError:
            # 跳过无权限访问的系统设备
            continue
    return scanners

def main():
    devices = {}
    SCAN_INTERVAL = 5  # 设备扫描间隔(秒)

    while True:
        # 扫描并添加新设备
        new_scanners = find_zebra_scanners()
        for dev in new_scanners:
            if dev.fd not in devices:
                print(f"已连接: {dev.name} ({dev.path})")
                devices[dev.fd] = dev

        if not devices:
            print("未检测到Zebra扫描器,等待重试...")
            time.sleep(SCAN_INTERVAL)
            continue

        # 监听设备输入,超时后重新扫描
        try:
            r, w, x = select(devices, [], [], SCAN_INTERVAL)
        except ValueError:
            # select前设备已断开,清理失效设备
            invalid_fds = []
            for fd in devices:
                try:
                    # 验证设备是否可用
                    devices[fd].path
                except OSError:
                    invalid_fds.append(fd)
            for fd in invalid_fds:
                print(f"已断开: {devices[fd].name}")
                del devices[fd]
            continue

        # 处理输入事件
        for fd in r:
            try:
                for event in devices[fd].read():
                    print(event)
            except OSError:
                # 读取时设备断开,移除设备
                print(f"已断开: {devices[fd].name}")
                del devices[fd]

if __name__ == "__main__":
    main()

代码说明

  • find_zebra_scanners():自动遍历系统输入设备,筛选出Zebra扫描器,跳过无权限访问的设备
  • 主循环:定期扫描设备,维护可用设备列表;监听输入事件时捕获异常,处理设备断开情况
  • 超时机制:避免select一直阻塞,确保设备断开后能及时重新扫描

内容的提问来源于stack exchange,提问作者Vanlon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 06:55:17