2

I have a barcode scanner connected to my RasPi without any tty, which means headless without a monitor. In other words, a keylogger for number inputs. This scanner reads numerical barcodes like GTIN or EAN. It works, the script is started by sh on boot. The script I use looks like that:

import sys

tStr = ''
while 1:
        fp = open('/dev/hidraw3', 'rb')
        buffer = fp.read(8)
        for c in buffer:
                if c:
                        if c == 40 or c == 88: # [ENTER-key]
                                function_to_handle_result (tStr)
                                tStr = ''
                        elif c == 98 or c == 39:
                                c = 0
                                tStr = tStr + str(c)
                        elif c > 29 and c < 39:
                                c = c - 29
                                tStr = tStr + str(c)
                        elif c > 88 and c < 98:
                                c = c - 88
                                tStr = tStr + str(c)

Now I want the user to be able to input numbers manually, in case that the barcode is damaged and/or not readable, and connected a numeric keyboard. Each of these two devices work separately with the script above, if I know the virtual file and its number, like '/dev/hidraw3'.

Now I want to combine the inputs to be able to access the values in one script and one function, and I want to guess the right hidraw-path.

This is my approach, which seems logical to me, but doesn't work. There is no error message, it just does nothing. What am I doing wrong ?

import sys
from pathlib import Path

t = ''

def handle_c(c):
        global t
        if c == 40 or c == 88:
                function_to_handle_result (t)
                t = ''
        elif c == 98 or c == 39:
                c = 0
                t = t + str(c)
        elif c > 29 and c < 39:
                c = c - 29
                t = t + str(c)
        elif c > 88 and c < 98:
                c = c-88
                t = t + str(c)
        return

hid = {}
f = {}
b = {}
c = {}
while 1:
        for i in range(10):
                hid[i] = '/dev/hidraw'+str(i) # guessing path
                if Path(hid[i]).exists(): # check if path exists
                        f[i] = open(hid[i], 'rb')
                        b[i] = f[i].read(8)
                        for c[i] in b[i]:
                                if c[i]:
                                        handle_c(c[i])

In earlier approaches I did not use dynamical variables like here, with the same result, it does nothing.

Thanks for your help.

ddlab
  • 918
  • 13
  • 28

1 Answers1

3

you can use python-evdev for accessing the numeric keyboard ( and also the barcode scanner ). it is a python implementation of the linux evdev interface that is based on events generated by the input devices, i.e. HID ( https://en.wikipedia.org/wiki/Evdev )

http://python-evdev.readthedocs.io/en/latest/tutorial.html ( for multiple devices see Reading events from multiple devices )

in https://khanhicetea.com/post/read_input_from_usb_keyboard_in_linux/ is code for using evdev with barcode scanner

ralf htp
  • 9,149
  • 4
  • 22
  • 34
  • Thanks for your reply. I know the barcode scanner script from the second link. This did not solve my problem with the multiple input. The 1st link with "Reading events from multiple devices" sounds like matching the problem. I'll go into it. Thanks :-) – ddlab Nov 12 '17 at 10:28
  • In the meantime I got the script running, as a combination of the two that Ralf suggested. I can read now endless keystrokes from mixed inputs HID, like keyboard, numpad, barcode scanner and RFID reader. The only thing I am stucking at the moment is the system language setting.. `locale.getdefaultlocale()` says 'de_DE','utf-8' as expected, but the recorded key events are english (KEY_Z => 'Y' and vice versa, and other keys similar), although my keyboard is german... – ddlab Nov 12 '17 at 16:45
  • in https://wiki.gentoo.org/wiki/Evdev#Keyboard_layout is how to set keyboard layout for evdev – ralf htp Nov 12 '17 at 17:11
  • as far as I understand, on a RaspPi without a monitor, only with (several) keyboards and a network cable, with NO graphical UI does not run X11 server. Am I right ? Thus any X11-setting are senseless. I tried every different settings I found for `10-evdev.conf` and `20-keyboard.conf`. Also `localectl set-keymap de`. What I do not understand is, that `locale` shows everything with `de_DE.UTF-8`, and `grep -v ^# /etc/locale.gen` as well. How can the OS recognise input events as english ? And YES, I did a reboot after every change. – ddlab Nov 12 '17 at 19:16
  • if you did not explicitely disable X server it is started on boot by default on Raspbian, you can check this by ssh into the pi and `ps -aux | grep X` ( http://jeffskinnerbox.me/posts/2016/Apr/27/howto-set-up-the-raspberry-pi-as-a-headless-device/ ) – ralf htp Nov 12 '17 at 20:10
  • I installed minibian, a very small debian, where almost everything needs to be installed manually. The answer of `ps -aux | grep X` is `1297 0.0 0.1 4212 1828 pts/0 S+ 10:13 0:00 grep X`. What does it mean ? – ddlab Nov 13 '17 at 09:15
  • Following the mentioned article (jeffskinnerbox), which is very worth to read, I tested X Windows with `systemctl get-default` and the answer is `multi-user.target`, which means, X is not running, so far I understand. – ddlab Nov 13 '17 at 09:25
  • means that there is no X server running – ralf htp Nov 13 '17 at 09:26
  • I continued this problem here: https://stackoverflow.com/questions/47262144/python-3-headless-rasppi-locale-de-de-not-possible-for-evdev – ddlab Nov 13 '17 at 10:27