最近参加了个比赛,须要用到扫码枪。html
经过上网查阅资料,发现扫码枪这种东西属于HID(Human Interface Device),扫描到结果后,数据发送到上位机的方式和键盘输入相似。
而且还获知,扫码枪发送完一串条形码序列后会输入一个回车符。python
因此,咱们的步骤就是:git
# coding:utf-8 from evdev import InputDevice, ecodes, list_devices, categorize import signal, sys import evdev import redis global dev devices = map(InputDevice, list_devices()) for device in devices: print(device.name)
因为个人树莓派上面只接了一个扫码枪,因此运行脚本结果:
这个就是扫码枪名称了。github
# coding:utf-8 from evdev import InputDevice, ecodes, list_devices, categorize import signal, sys import evdev import redis import requests scancodes = { # Scancode: ASCIICode 0: None, 1: u'ESC', 2: u'1', 3: u'2', 4: u'3', 5: u'4', 6: u'5', 7: u'6', 8: u'7', 9: u'8', 10: u'9', 11: u'0', 12: u'-', 13: u'=', 14: u'BKSP', 15: u'TAB', 16: u'q', 17: u'w', 18: u'e', 19: u'r', 20: u't', 21: u'y', 22: u'u', 23: u'i', 24: u'o', 25: u'p', 26: u'[', 27: u']', 28: u'CRLF', 29: u'LCTRL', 30: u'a', 31: u's', 32: u'd', 33: u'f', 34: u'g', 35: u'h', 36: u'j', 37: u'k', 38: u'l', 39: u';', 40: u"'", 41: u'`', 42: u'LSHFT', 43: u'\\', 44: u'z', 45: u'x', 46: u'c', 47: u'v', 48: u'b', 49: u'n', 50: u'm', 51: u',', 52: u'.', 53: u'/', 54: u'RSHFT', 56: u'LALT', 100: u'RALT',57:u" ", 74:u"-" } scancodes_leftshift = { # Scancode: ASCIICode 0: None, 1: u'ESC', 2: u'!', 3: u'@', 4: u'#', 5: u'$', 6: u'%', 7: u'^', 8: u'&', 9: u'*', 10: u'(', 11: u')', 12: u'_', 13: u'+', 14: u'BKSP', 15: u'TAB', 16: u'Q', 17: u'W', 18: u'E', 19: u'R', 20: u'T', 21: u'Y', 22: u'U', 23: u'I', 24: u'O', 25: u'P', 26: u'{', 27: u'}', 28: u'CRLF', 29: u'LCTRL', 30: u'A', 31: u'S', 32: u'D', 33: u'F', 34: u'G', 35: u'H', 36: u'J', 37: u'K', 38: u'L', 39: u':', 40: u'"', 41: u'~', 42: u'LSHFT', 43: u'|', 44: u'Z', 45: u'X', 46: u'C', 47: u'V', 48: u'B', 49: u'N', 50: u'M', 51: u'<', 52: u'>', 53: u'?', 54: u'RSHFT', 56: u'LALT', 100: u'RALT',57:u" ", 74:u"-" } dev = None #设备 barCodeDeviceString = "Newland Auto-ID NLS IOTC PRDs HID KBW" def usb_scan_dev(): global dev devices = map(InputDevice, list_devices()) for device in devices: if device.name == barCodeDeviceString: dev = InputDevice(device.fn) if not dev: print("not found dev") return def signal_handler(signalnum, frame): print(signalnum) print(frame) #根据退出信号,释放输入设备 print("Stopping") dev.ungrab() sys.exit(0) # 信号处理函数 # signal.SIGINT-终止进程 # 若输入ctrl+c,则按照signal_handler函数对其进行处理 signal.signal(signal.SIGINT, signal_handler) dev_.grab() barcode = "" keymap = scancodes for event in dev_.read_loop(): if event.type == ecodes.EV_KEY: data = categorize(event) # shift 键 if data.scancode == 42: # 按下 if data.keystate == 1: keymap = scancodes_leftshift # 未按下 elif data.keystate == 0: keymap = scancodes # 若按下回车键 elif data.scancode == 28 and data.keystate == 1: print("s" + str(Serial_Number) +": " + barcode) put_code(barcode) break # 按下普通键 # 74才是"-"的编码 elif ((data.scancode >= 1 and data.scancode <= 57) or data.scancode == 74) and data.keystate == 1: barcode += keymap[data.scancode] # 表示该py文件做为单独脚本运行时,即执行usb_scan_dev方法 if __name__ == "__main__": usb_scan_dev()
如今运行该脚本便可获取商品条形码序列了:
可是如今问题又来了,光有了条形码序列也没用啊,咱们须要的是详细的商品信息。web
在此先安利一个很是不错的查询接口:
https://github.com/MZCretin/RollToolsApiredis
根据里面的描述,咱们能够将得到的这个序列化序号组成一个连接:api
Request_url = "http://www.mxnzp.com/api/barcode/goods/details?barcode=" + barcode
而后Get请求就行:svg
r = requests.get(Request_url, timeout=0.1) print(r.text)
完整代码:函数
# coding:utf-8 from evdev import InputDevice, ecodes, list_devices, categorize import signal, sys import evdev import redis import requests scancodes = { # Scancode: ASCIICode 0: None, 1: u'ESC', 2: u'1', 3: u'2', 4: u'3', 5: u'4', 6: u'5', 7: u'6', 8: u'7', 9: u'8', 10: u'9', 11: u'0', 12: u'-', 13: u'=', 14: u'BKSP', 15: u'TAB', 16: u'q', 17: u'w', 18: u'e', 19: u'r', 20: u't', 21: u'y', 22: u'u', 23: u'i', 24: u'o', 25: u'p', 26: u'[', 27: u']', 28: u'CRLF', 29: u'LCTRL', 30: u'a', 31: u's', 32: u'd', 33: u'f', 34: u'g', 35: u'h', 36: u'j', 37: u'k', 38: u'l', 39: u';', 40: u"'", 41: u'`', 42: u'LSHFT', 43: u'\\', 44: u'z', 45: u'x', 46: u'c', 47: u'v', 48: u'b', 49: u'n', 50: u'm', 51: u',', 52: u'.', 53: u'/', 54: u'RSHFT', 56: u'LALT', 100: u'RALT',57:u" " } scancodes_leftshift = { # Scancode: ASCIICode 0: None, 1: u'ESC', 2: u'!', 3: u'@', 4: u'#', 5: u'$', 6: u'%', 7: u'^', 8: u'&', 9: u'*', 10: u'(', 11: u')', 12: u'_', 13: u'+', 14: u'BKSP', 15: u'TAB', 16: u'Q', 17: u'W', 18: u'E', 19: u'R', 20: u'T', 21: u'Y', 22: u'U', 23: u'I', 24: u'O', 25: u'P', 26: u'{', 27: u'}', 28: u'CRLF', 29: u'LCTRL', 30: u'A', 31: u'S', 32: u'D', 33: u'F', 34: u'G', 35: u'H', 36: u'J', 37: u'K', 38: u'L', 39: u':', 40: u'"', 41: u'~', 42: u'LSHFT', 43: u'|', 44: u'Z', 45: u'X', 46: u'C', 47: u'V', 48: u'B', 49: u'N', 50: u'M', 51: u'<', 52: u'>', 53: u'?', 54: u'RSHFT', 56: u'LALT', 100: u'RALT',57:u" " } dev = None #设备 barCodeDeviceString = "Newland Auto-ID NLS IOTC PRDs HID KBW" def usb_scan_dev(): global dev devices = map(InputDevice, list_devices()) for device in devices: if device.name == barCodeDeviceString: dev = InputDevice(device.fn) if not dev: print("not found dev") return def signal_handler(signalnum, frame): print(signalnum) print(frame) #根据退出信号,释放输入设备 print("Stopping") dev.ungrab() sys.exit(0) # 信号处理函数 # signal.SIGINT-终止进程 # 若输入ctrl+c,则按照signal_handler函数对其进行处理 signal.signal(signal.SIGINT, signal_handler) dev.grab() #成为全部事件中惟一接收者 barcode = "" keymap = scancodes for event in dev.read_loop(): if event.type == ecodes.EV_KEY: data = categorize(event) if data.scancode == 42: if data.keystate == 1: keymap = scancodes_leftshift if data.keystate == 0: keymap = scancodes #只接收输入,不接收输出,也不接收回车 if data.keystate == 1 and data.scancode != 42: if data.scancode == 28: print(barcode) Request_url = "http://www.mxnzp.com/api/barcode/goods/details?barcode=" + barcode r = requests.get(Request_url, timeout=0.1) print(r.text) barcode = "" else: if data.scancode >= 1 and data.scancode <= 57: barcode += keymap[data.scancode] # 表示该py文件做为单独脚本运行时,即执行usb_scan_dev方法 if __name__ == "__main__": usb_scan_dev()
结果:
oop
附:
evdev:https://python-evdev.readthedocs.io/en/latest/apidoc.html