I'm a newbie with this python thing but I'm trying to put a barcode reader to work. I'm using evdev with a raspi and a 16x2 LCD. My problem is simple but I can not find the solution for it.
Link for evdev:
Initial code I get from:
How can I get a String from HID device in Python with evdev?
To discard mistakes i want to make a timer countdown. In that countdown the user has the possibility of correct the barcode that he is using. For example if he, by mistake, pass the wrong barcode he has the possibility to correct the reading in the next 10 seconds.
#!/usr/bin/python3
import evdev, asyncio, sys, lcd, signal, dadosintervencao, time
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'
}
capscodes = {
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'
}
def parsedados(msg):
codigo = (msg.split('None',1))
dado1 = codigo[0]
if len(codigo) < 2:
return False
else:
dado2 = codigo[1]
return dado1, dado2
@asyncio.coroutine
def countdown(segundo):
start = int(time.time())
elapsed = 0
while segundo > 0 and elapsed !=1:
print(str(barcodereader.async_read()))
elapsed = segundo - (int(time.time())-start)
yield from asyncio.sleep(1.0)
print (elapsed)
@asyncio.coroutine
def print_events(device):
caps = Fals
maquina = False
x=''
while True:
events = yield from device.async_read()
for event in events:
if event.type == evdev.ecodes.EV_KEY:
data = evdev.categorize(event)
if data.scancode == 42:
if data.keystate == 1:
caps = True
if data.keystate == 0:
caps = False
if data.keystate == 1: # Down events only
if caps:
key_lookup = u'{}'.format(capscodes.get(data.scancode)) or u'UNKNOWN:[{}]'.format(data.scancode) # Lookup or return UNKNOWN:XX
else:
key_lookup = u'{}'.format(scancodes.get(data.scancode)) or u'UNKNOWN:[{}]'.format(data.scancode) # Lookup or return UNKNOWN:XX
if (data.scancode != 42) and (data.scancode != 28):
x += key_lookup # Print it all out!
if(data.scancode == 28):
codigo = parsedados(x)
if codigo == False:
dadosintervencao.error_handler()
print('Passe OT novamente')
elif codigo[0] != 'Estado' and maquina == False:
maquina = True
dadosintervencao.dadosOT(codigo[0],codigo[1])
print ('Maquina ' + codigo[0])
elif codigo[0] =='Estado' and maquina == True:
maquina = False
estado = codigo[1]
print('Estado '+ estado)
print('Espera 10 seg')
# ciclo para esperar 10 segundos antes de enviar dados para a base de dados
#Att this point it wait for another barcode
yield from countdown(10)
dadosintervencao.estado(estado)
else:
print('Passe OT novamente')
maquina = False
dadosintervencao.error_handler()
x = ''
def iniciar():
barcodereader = evdev.InputDevice('/dev/input/event0')
task1 = asyncio.async(print_events(barcodereader))
task2 = asyncio.async(countdown(0))
yield from task1
yield from task2
def main():
loop = asyncio.get_event_loop()
asyncio.async(iniciar())
lcd.limpar()
print('Start %s' %asyncio.Task.all_tasks(loop))
loop.run_forever()
def signal_term_handler(signal, frame):
lcd.desligar()
sys.exit(0)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
lcd.desligar()
pass
sys.exit("Usada teclas de Crl+C")
except:
signal.signal(signal.SIGTERM, signal_term_handler)
In the end of the countdown the data is sent to some database (not yet implemented). The function (in this case I'm trying to use a coroutine) countdown is suppose to run concurrently with the evdev asyncio_read(). So when I pass a new barcode it cancel the countdown and start over again. I'm in this for a couple of days and did not find any solution.