寻求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
相关产品推荐
相关产品推荐

