Skip to content

Instantly share code, notes, and snippets.

@JoachimL
Last active November 8, 2022 07:33
  • Star 21 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save JoachimL/1629f701fdb38427091710fc0caef67d to your computer and use it in GitHub Desktop.
Python USB barcode reader
import evdev
from evdev import *
from azure.storage.queue import QueueService, QueueMessageFormat
import threading
import time
from queue import *
import datetime
# responsible for uploading the barcodes to the azure storage queue.
class BarcodeUploader:
def __init__(self):
# Instiantiate the azure queue service (from the azure.storage.queue package)
self.queue_service = QueueService(account_name='wereoutof', account_key='your-key-here')
# azure functions is _very_ confused is the text isn't base64 encoded
self.queue_service.encode_function = QueueMessageFormat.text_base64encode
# use a simple queue to avoid blocking operations
self.queue = LifoQueue()
t = threading.Thread(target=self.worker, args=())
t.daemon = True
t.start()
# processes all messages (barcodes) in queue - uploading them to azure one by one
def worker(self):
while True:
while not self.queue.empty():
try:
barcode = self.queue.get()
self.queue_service.put_message('barcodes', u'account-key:' + barcode)
except Exception as exc:
print("Exception occured when uploading barcode:" + repr(exc))
# re-submit task into queue
self.queue.task_done()
self.queue.put(barcode)
else:
print("Barcode " + barcode + " registered")
self.queue.task_done()
time.sleep(1)
def register(self, barcode):
print "Registering barcode " + barcode + "..."
self.queue.put(barcode)
current_barcode = ""
# Reads barcode from "device"
def readBarcodes():
global current_barcode
print ("Reading barcodes from device")
for event in device.read_loop():
if event.type == evdev.ecodes.EV_KEY and event.value == 1:
keycode = categorize(event).keycode
if keycode == 'KEY_ENTER':
uploader.register(current_barcode)
current_barcode = ""
else:
current_barcode += keycode[4:]
# Finds the input device with the name "Barcode Reader ".
# Could and should be parameterized, of course. Device name as cmd line parameter, perhaps?
def find_device():
device_name = 'Barcode Reader '
devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
for d in devices:
if d.name == device_name:
print("Found device " + d.name)
device = d
return device
# Find device...
device = find_device()
if device is None:
print("Unable to find " + device_name)
else:
#... instantiate the uploader...
uploader = BarcodeUploader()
# ... and read the bar codes.
readBarcodes()
@markusressel
Copy link

markusressel commented Oct 15, 2020

Thx, this has been very helpful 🥰
If you want to prevent the barcode scanner from cluttering up your TTY, have a look at this:
https://stackoverflow.com/questions/63478999/how-to-make-linux-ignore-a-keyboard-while-keeping-it-available-for-my-program-to/63531743#63531743
EDIT:
I just found out that evdev also supports this
EDIT2:
I have written a small daemon that should hopefully make it easier for others to read the input of barcode scanners and send it to some other application via websocket: https://github.com/markusressel/barcode-server

@JoachimL
Copy link
Author

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment