Skip to content

Commit e63e00e

Browse files
committed
Drivers for the barcode and the rfid scanner
1 parent d273d30 commit e63e00e

File tree

3 files changed

+211
-0
lines changed

3 files changed

+211
-0
lines changed

drivers/barcode.py

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import argparse
2+
import logging
3+
from thunderclient import Thunder
4+
from evdev import InputDevice, list_devices, ecodes
5+
from evdev import categorize
6+
7+
logger = logging.getLogger(__name__)
8+
9+
10+
def read_codes(device):
11+
events = (e for e in device.read_loop() if e.type == ecodes.EV_KEY)
12+
events = map(categorize, events)
13+
events = (e for e in events if e.keystate == e.key_up)
14+
15+
buff = []
16+
17+
for e in events:
18+
if e.scancode == ecodes.KEY_ENTER:
19+
ascii = [e.keycode.split('_')[1] for e in buff]
20+
buff = []
21+
yield ''.join(ascii)
22+
else:
23+
buff.append(e)
24+
25+
26+
def main(device_name, host, port, apikey, apisecret, verbose=False):
27+
# Configure logging to the console if requested.
28+
if verbose:
29+
handler = logging.StreamHandler()
30+
handler.setLevel(logging.DEBUG)
31+
logger.addHandler(handler)
32+
logger.setLevel(logging.DEBUG)
33+
34+
devices = map(InputDevice, list_devices())
35+
devices = [d for d in devices if d.name.strip() == device_name]
36+
37+
assert devices, ('No Barcode Reader device found (did you forget to run '
38+
'the script as root?).')
39+
40+
device = devices[0]
41+
device.grab()
42+
43+
logger.debug('Connected to \'%s\'.', device.name.strip())
44+
tc = Thunder(apikey, apisecret, host, port)
45+
46+
for code in read_codes(device):
47+
tc.send_message_to_channel('products', code)
48+
logger.debug('Code %s has been sent to the \'products\' channel.', code)
49+
50+
51+
if __name__ == '__main__':
52+
parser = argparse.ArgumentParser()
53+
parser.add_argument('device', type=str,
54+
help='The name of the device to read from.')
55+
parser.add_argument('host', type=str,
56+
help='Thunderpush host to communicate with.')
57+
parser.add_argument('apikey', type=str)
58+
parser.add_argument('apisecret', type=str)
59+
parser.add_argument('--port', type=int, default=80,
60+
help='Thunderpush port (default 80).')
61+
parser.add_argument('-v', '--verbose', help='Increase output verbosity.',
62+
action='store_true')
63+
args = parser.parse_args()
64+
main(args.device, args.host, args.port, args.apikey, args.apisecret,
65+
args.verbose)
66+

drivers/rfid.py

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import time
2+
import serial
3+
import logging
4+
import argparse
5+
import redis
6+
from functools import wraps
7+
8+
logger = logging.getLogger(__name__)
9+
10+
11+
def throttle(seconds):
12+
def decorator(func):
13+
func.last_call = 0
14+
15+
def reset_timer():
16+
func.reset_timer = 0
17+
18+
func.reset_timer = reset_timer
19+
20+
@wraps(func)
21+
def wrapper(*args, **kwargs):
22+
if time.time() - func.last_call > seconds:
23+
func.last_call = time.time()
24+
return func(*args, **kwargs)
25+
return wrapper
26+
return decorator
27+
28+
29+
@throttle(seconds=1)
30+
def parse_code(data):
31+
try:
32+
return int('0x{}'.format(data.decode('ascii').strip()), 16)
33+
except ValueError:
34+
# Invalid value has been read. Discard it and do not wait before
35+
# reading the next value.
36+
parse_code.reset_timer()
37+
return None
38+
39+
40+
def parse_codes(ser):
41+
while True:
42+
code = parse_code(ser.readline())
43+
if code is not None:
44+
yield code
45+
46+
47+
def main(dev, rate, host, port, channel, verbose):
48+
# Configure logging to the console if requested.
49+
if verbose:
50+
handler = logging.StreamHandler()
51+
handler.setLevel(logging.DEBUG)
52+
logger.addHandler(handler)
53+
logger.setLevel(logging.DEBUG)
54+
55+
r = redis.StrictRedis(
56+
host=host,
57+
port=port
58+
)
59+
60+
logger.debug('Starting reading from %s with baud rate %d.', dev, rate)
61+
with serial.Serial(dev, rate) as ser:
62+
# Discard the first value as it contains just a welcome message
63+
ser.readline()
64+
logger.debug('The connection has been estabilished and the '
65+
'welcome message read.')
66+
67+
try:
68+
for code in parse_codes(ser):
69+
r.publish(channel, code)
70+
logger.debug('Code %d has been sent to the \'%s\' channel.',
71+
channel, code)
72+
except KeyboardInterrupt:
73+
logger.debug('CTRL-C received. Shutting down...')
74+
75+
76+
if __name__ == '__main__':
77+
parser = argparse.ArgumentParser(
78+
description='Listens for input from a RFID reader and publishes it '
79+
'to a Redis channel.'
80+
)
81+
parser.add_argument('device', type=str, help='A device file to read from.')
82+
parser.add_argument('--channel', type=str, default='cards',
83+
help='Redis channel to send messages to.')
84+
parser.add_argument('--host', type=str, default='localhost',
85+
help='Redis host (default localhost).')
86+
parser.add_argument('--port', type=int, default=6379,
87+
help='Redis port (default 6379).')
88+
parser.add_argument('--rate', type=int, default=115200,
89+
help='The baud rate (default: 115200).')
90+
parser.add_argument('-v', '--verbose', help='Increase output verbosity.',
91+
action='store_true')
92+
args = parser.parse_args()
93+
main(**vars(args))

drivers/rfid_forwarder.py

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import logging
2+
import argparse
3+
import redis
4+
from thunderclient import Thunder
5+
6+
logger = logging.getLogger(__name__)
7+
8+
9+
def main(apikey, apisecret, rhost, rport, rchannel, thost, tport, tchannel,
10+
verbose=False):
11+
# Configure logging to the console if requested.
12+
if verbose:
13+
handler = logging.StreamHandler()
14+
handler.setLevel(logging.DEBUG)
15+
logger.addHandler(handler)
16+
logger.setLevel(logging.DEBUG)
17+
18+
tc = Thunder(apikey, apisecret, thost, tport)
19+
r = redis.StrictRedis(host=rhost, port=rport)
20+
p = r.pubsub()
21+
p.subscribe(rchannel)
22+
23+
try:
24+
for msg in filter(lambda msg: msg['type'] == 'message', p.listen()):
25+
26+
code = int(msg['data'].decode('utf-8'))
27+
tc.send_message_to_channel('cards', code)
28+
logger.debug('Code %d has been forwarded.', code)
29+
except KeyboardInterrupt:
30+
logger.debug('CTRL-C received. Shutting down...')
31+
32+
33+
if __name__ == '__main__':
34+
parser = argparse.ArgumentParser()
35+
parser.add_argument('apikey', type=str)
36+
parser.add_argument('apisecret', type=str)
37+
parser.add_argument('--thost', type=str, default='localhost',
38+
help='Thunderpush host (default: localhost).')
39+
parser.add_argument('--tchannel', type=str, default='cards',
40+
help='Thunderpush channel name (default: cards).')
41+
parser.add_argument('--tport', type=int, default=80,
42+
help='Thunderpush port (default: 80).')
43+
parser.add_argument('--rhost', type=str, default='localhost',
44+
help='Redis host (default: localhost).')
45+
parser.add_argument('--rport', type=int, default=6379,
46+
help='Redis port (default: 6379).')
47+
parser.add_argument('--rchannel', type=str, default='cards',
48+
help='Redis channel name (default: cards).')
49+
parser.add_argument('-v', '--verbose', help='Increase output verbosity.',
50+
action='store_true')
51+
args = parser.parse_args()
52+
main(**vars(args))

0 commit comments

Comments
 (0)