Hi,
I have struggled to setup a service to integrate with my USB barcode scanner.
The idea is that a service gets input from /dev/hidraw1 which comes from the usb scanner. The input is decoded and then the recognised code is sent to mqtt.
The idea was tested using this code running directly on the device. And it worked as designed.
# Props to user brechmos for sharing the code here: https://www.raspberrypi.org/forums/viewtopic.php?t=55100
# Tested with the following barcode scanner
# macbook# ioreg -p IOUSB
# <snip>
# | +-o WIT 122-UFS V2.03@14200000 <class AppleUSBDevice, id 0x10000c3c4, registered, matched, active, busy 0 (6 ms), retain 14>
# WIT 122-UFS V2.03:
# Product ID: 0x1010
# Vendor ID: 0x05fe (CHIC TECHNOLOGY CORP)
# Version: 0.01
# Speed: Up to 12 Mb/sec
# Manufacturer: WIT Electron Company
# Location ID: 0x14200000 / 4
# Current Available (mA): 500
# Current Required (mA): 500
# Extra Operating Current (mA): 0
import sys
import paho.mqtt.client as paho
import json
hid = { 4: 'a', 5: 'b', 6: 'c', 7: 'd', 8: 'e', 9: 'f', 10: 'g', 11: 'h', 12: 'i', 13: 'j', 14: 'k', 15: 'l', 16: 'm', 17: 'n', 18: 'o', 19: 'p', 20: 'q', 21: 'r', 22: 's', 23: 't', 24: 'u', 25: 'v', 26: 'w', 27: 'x', 28: 'y', 29: 'z', 30: '1', 31: '2', 32: '3', 33: '4', 34: '5', 35: '6', 36: '7', 37: '8', 38: '9', 39: '0', 44: ' ', 45: '-', 46: '=', 47: '[', 48: ']', 49: '\\', 51: ';' , 52: '\'', 53: '~', 54: ',', 55: '.', 56: '/' }
hid2 = { 4: 'A', 5: 'B', 6: 'C', 7: 'D', 8: 'E', 9: 'F', 10: 'G', 11: 'H', 12: 'I', 13: 'J', 14: 'K', 15: 'L', 16: 'M', 17: 'N', 18: 'O', 19: 'P', 20: 'Q', 21: 'R', 22: 'S', 23: 'T', 24: 'U', 25: 'V', 26: 'W', 27: 'X', 28: 'Y', 29: 'Z', 30: '!', 31: '@', 32: '#', 33: '$', 34: '%', 35: '^', 36: '&', 37: '*', 38: '(', 39: ')', 44: ' ', 45: '_', 46: '+', 47: '{', 48: '}', 49: '|', 51: ':' , 52: '"', 53: '~', 54: '<', 55: '>', 56: '?' }
fp = open('/dev/hidraw1', 'rb')
client = paho.Client()
client.connect('localhost', 1883, 60)
ss = ""
shift = False
done = False
while not done:
## Get the character from the HID
buffer = fp.read(8)
for c in buffer:
if ord(c) > 0:
## 40 is carriage return which signifies
## we are done looking for characters
if int(ord(c)) == 40:
print ss
#we need to check if this is one of our qrcodes and alert accordingly. We will insert a class to get the wallet. if the wallet was retrieved then fine
#essentially we just implement the passenger checking in the passenger class
client.publish("ixzbus/trip/boarded", payload=ss, qos=1)
#done = True
ss=""
break;
## If we are shifted then we have to
## use the hid2 characters.
if shift:
## If it is a '2' then it is the shift key
if int(ord(c)) == 2 :
shift = True
## if not a 2 then lookup the mapping
else:
ss += hid2[ int(ord(c)) ]
shift = False
## If we are not shifted then use
## the hid characters
else:
## If it is a '2' then it is the shift key
if int(ord(c)) == 2 :
shift = True
## if not a 2 then lookup the mapping
else:
ss += hid[ int(ord(c)) ]
#print ss
Then we tried to convert it into a service using this code. However it now does not work as the reading from /dev/hidraw1 now returns always 0 even though clearly it is reading something. We confirmed from the logs.
import logging
import paho.mqtt.client as mqtt
log = logging.getLogger(__name__)
def start(**settings):
try:
if log.isEnabledFor(logging.DEBUG):
log.debug("Starting Debug SERVICE with settings: {:}".format(settings))
log.warn("Starting Barcode Scanner Service")
# Start service and wait.
hid = { 4: 'a', 5: 'b', 6: 'c', 7: 'd', 8: 'e', 9: 'f', 10: 'g', 11: 'h', 12: 'i', 13: 'j', 14: 'k', 15: 'l', 16: 'm', 17: 'n', 18: 'o', 19: 'p', 20: 'q', 21: 'r', 22: 's', 23: 't', 24: 'u', 25: 'v', 26: 'w', 27: 'x', 28: 'y', 29: 'z', 30: '1', 31: '2', 32: '3', 33: '4', 34: '5', 35: '6', 36: '7', 37: '8', 38: '9', 39: '0', 44: ' ', 45: '-', 46: '=', 47: '[', 48: ']', 49: '\\', 51: ';' , 52: '\'', 53: '~', 54: ',', 55: '.', 56: '/' }
hid2 = { 4: 'A', 5: 'B', 6: 'C', 7: 'D', 8: 'E', 9: 'F', 10: 'G', 11: 'H', 12: 'I', 13: 'J', 14: 'K', 15: 'L', 16: 'M', 17: 'N', 18: 'O', 19: 'P', 20: 'Q', 21: 'R', 22: 'S', 23: 'T', 24: 'U', 25: 'V', 26: 'W', 27: 'X', 28: 'Y', 29: 'Z', 30: '!', 31: '@', 32: '#', 33: '$', 34: '%', 35: '^', 36: '&', 37: '*', 38: '(', 39: ')', 44: ' ', 45: '_', 46: '+', 47: '{', 48: '}', 49: '|', 51: ':' , 52: '"', 53: '~', 54: '<', 55: '>', 56: '?' }
try:
fp = open('/dev/hidraw1', 'rb')
client = mqtt.Client()
client.connect('localhost', 1883, 60)
except:
log.exception("Barcode Service is Unable to open hidraw1 or connect")
raise
ss = ""
shift = False
done = False
while not done:
## Get the character from the HID
buffer = fp.read(8)
for c in buffer:
log.warn("Barcode service received " + str(int(ord(c))))
if ord(c) > 0:
## 40 is carriage return which signifies
## we are done looking for characters
if int(ord(c)) == 40:
client.publish("ixzbus/trip/boarded", payload=ss, qos=1)
log.info("Barcode Scanner received and published ")
log.info(ss)
ss=""
break;
## If we are shifted then we have to
## use the hid2 characters.
if shift:
## If it is a '2' then it is the shift key
if int(ord(c)) == 2 :
shift = True
## if not a 2 then lookup the mapping
else:
ss += hid2[ int(ord(c)) ]
shift = False
## If we are not shifted then use
## the hid characters
else:
## If it is a '2' then it is the shift key
if int(ord(c)) == 2 :
shift = True
## if not a 2 then lookup the mapping
else:
ss += hid[ int(ord(c)) ]
except Exception:
log.exception("Failed to start Barcode scanner SERVICE")
raise
finally:
log.info("Stopping SERVICE")
# Stop everything, close connections etc.
Is this a problem from my code or is it a problem with having it run as a service? Is there any other way to get this sorted? Will other code that listen to BLE or other devices be implemented as services?