-
Notifications
You must be signed in to change notification settings - Fork 403
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Changed the installscripts/buster-install-default.sh to use new Regis…
…terDevice.py.Multi Added requirement for PN532 and RC522 installation direct to RegisterDevice.py.Multi if the user chooses it.
- Loading branch information
Markus Prochaska
authored and
Markus Prochaska
committed
Jul 2, 2020
1 parent
bc1d675
commit 14f4df3
Showing
4 changed files
with
273 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,211 @@ | ||
#!/usr/bin/env python3 | ||
# There are a variety of RFID readers out there, USB and non-USB variants. | ||
# This might create problems in recognizing the reader you are using. | ||
# We haven't found the silver bullet yet. If you can contribute to this | ||
# quest, please comment in the issue thread or create pull requests. | ||
# ALTERNATIVE SCRIPTS: | ||
# If you encounter problems with this script Reader.py | ||
# consider and test one of the alternatives in the same scripts folder. | ||
# Replace the Reader.py file with one of the following files: | ||
# * Reader.py.experimental | ||
# This alternative Reader.py script was meant to cover not only USB readers but more. | ||
# It can be used to replace Reader.py if you have readers such as | ||
# MFRC522, RDM6300 or PN532. | ||
# * Reader.py.kkmoonRFIDreader | ||
# KKMOON RFID Reader which appears twice in the devices list as HID 413d:2107 | ||
# and this required to check "if" the device is a keyboard. | ||
|
||
# import string | ||
# import csv | ||
# This alternative Reader.py script was meant to cover not only USB readers but more. | ||
# It can be used to replace Reader.py if you have readers such as | ||
# MFRC522, RDM6300 or PN532. | ||
# Please use the github issue threads to share bugs and improvements | ||
# or create pull requests. | ||
import multiprocessing | ||
try: | ||
from multiprocessing import SimpleQueue | ||
except ImportError: | ||
from multiprocessing.queues import SimpleQueue | ||
import os.path | ||
import sys | ||
|
||
import serial | ||
import string | ||
import RPi.GPIO as GPIO | ||
import logging | ||
from enum import Enum | ||
from evdev import InputDevice, ecodes, list_devices | ||
from select import select | ||
# Workaround: when using RC522 reader with pirc522 pkg the py532lib pkg may not be installed and vice-versa | ||
try: | ||
import pirc522 | ||
from py532lib.i2c import * | ||
from py532lib.mifare import * | ||
except ImportError: | ||
pass | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
class EDevices(Enum): | ||
MFRC522 = 0 | ||
RDM6300 = 1 | ||
PN532 = 2 | ||
|
||
|
||
def get_devices(): | ||
return [InputDevice(fn) for fn in list_devices()] | ||
devices = [InputDevice(fn) for fn in list_devices()] | ||
devices.append(NonUsbDevice(EDevices.MFRC522.name)) | ||
devices.append(NonUsbDevice(EDevices.RDM6300.name)) | ||
devices.append(NonUsbDevice(EDevices.PN532.name)) | ||
return devices | ||
|
||
|
||
class Reader: | ||
reader = None | ||
class NonUsbDevice(object): | ||
name = None | ||
|
||
def __init__(self): | ||
self.reader = self | ||
path = os.path.dirname(os.path.realpath(__file__)) | ||
def __init__(self, name, phys=''): | ||
self.name = name | ||
self.phys = phys | ||
|
||
|
||
class UsbReader(object): | ||
def __init__(self, device): | ||
self.keys = "X^1234567890XXXXqwertzuiopXXXXasdfghjklXXXXXyxcvbnmXXXXXXXXXXXXXXXXXXXXXXX" | ||
if not os.path.isfile(path + '/deviceName.txt'): | ||
sys.exit('Please run RegisterDevice.py first') | ||
else: | ||
with open(path + '/deviceName.txt', 'r') as f: | ||
deviceName = f.read() | ||
devices = get_devices() | ||
for device in devices: | ||
if device.name == deviceName: | ||
self.dev = device | ||
break | ||
try: | ||
self.dev | ||
except: | ||
sys.exit('Could not find the device %s\n. Make sure is connected' % deviceName) | ||
self.dev = device | ||
|
||
def readCard(self): | ||
from select import select | ||
stri = '' | ||
key = '' | ||
while key != 'KEY_ENTER': | ||
r, w, x = select([self.dev], [], []) | ||
select([self.dev], [], []) | ||
for event in self.dev.read(): | ||
if event.type == 1 and event.value == 1: | ||
stri += self.keys[event.code] | ||
# print( keys[ event.code ] ) | ||
key = ecodes.KEY[event.code] | ||
return stri[:-1] | ||
|
||
|
||
class Mfrc522Reader(object): | ||
def __init__(self): | ||
self.device = pirc522.RFID() | ||
|
||
def readCard(self): | ||
# Scan for cards | ||
self.device.wait_for_tag() | ||
(error, tag_type) = self.device.request() | ||
|
||
if not error: | ||
logger.info("Card detected.") | ||
# Perform anti-collision detection to find card uid | ||
(error, uid) = self.device.anticoll() | ||
if not error: | ||
card_id = ''.join((str(x) for x in uid)) | ||
logger.info(card_id) | ||
return card_id | ||
logger.debug("No Device ID found.") | ||
return None | ||
|
||
@staticmethod | ||
def cleanup(): | ||
GPIO.cleanup() | ||
|
||
|
||
class Rdm6300Reader: | ||
def __init__(self): | ||
device = '/dev/ttyS0' | ||
baudrate = 9600 | ||
ser_timeout = 0.1 | ||
self.last_card_id = '' | ||
try: | ||
self.rfid_serial = serial.Serial(device, baudrate, timeout=ser_timeout) | ||
except serial.SerialException as e: | ||
logger.error(e) | ||
exit(1) | ||
|
||
def readCard(self): | ||
byte_card_id = b'' | ||
|
||
try: | ||
while True: | ||
try: | ||
read_byte = self.rfid_serial.read() | ||
|
||
if read_byte == b'\x02': # start byte | ||
while read_byte != b'\x03': # end bye | ||
read_byte = self.rfid_serial.read() | ||
byte_card_id += read_byte | ||
|
||
card_id = byte_card_id.decode('utf-8') | ||
byte_card_id = '' | ||
card_id = ''.join(x for x in card_id if x in string.printable) | ||
|
||
# Only return UUIDs with correct length | ||
if len(card_id) == 12 and card_id != self.last_card_id: | ||
self.last_card_id = card_id | ||
self.rfid_serial.reset_input_buffer() | ||
return self.last_card_id | ||
|
||
else: # wrong UUID length or already send that UUID last time | ||
self.rfid_serial.reset_input_buffer() | ||
|
||
except ValueError as ve: | ||
logger.errror(ve) | ||
|
||
except serial.SerialException as se: | ||
logger.error(se) | ||
|
||
def cleanup(self): | ||
self.rfid_serial.close() | ||
|
||
|
||
class Pn532Reader: | ||
def __init__(self): | ||
pn532 = Pn532_i2c() | ||
self.device = Mifare() | ||
self.device.SAMconfigure() | ||
self.device.set_max_retries(MIFARE_WAIT_FOR_ENTRY) | ||
|
||
def readCard(self): | ||
return str(+int('0x' + self.device.scan_field().hex(), 0)) | ||
|
||
def cleanup(self): | ||
# Not sure if something needs to be done here. | ||
logger.debug("PN532Reader clean up.") | ||
|
||
|
||
class Reader(object): | ||
def __init__(self): | ||
self.reader = self | ||
self.devs = list() | ||
path = os.path.dirname(os.path.realpath(__file__)) | ||
if not os.path.isfile(path + '/deviceName.txt'): | ||
sys.exit('Please run RegisterDevice.py first') | ||
else: | ||
with open(path + '/deviceName.txt', 'r') as f: | ||
device_keys = f.readlines() | ||
devices = get_devices() | ||
for device in devices: | ||
for dev_key in device_keys: | ||
dev_name_phys = dev_key.rstrip().split(';', 1) | ||
dev_name = dev_name_phys[0] | ||
dev_phys = '' | ||
if len(dev_name_phys) > 1: | ||
dev_phys = dev_name_phys[1] | ||
if device.name == dev_name and device.phys == dev_phys: | ||
if dev_name == 'MFRC522': | ||
self.devs.append(Mfrc522Reader()) | ||
elif dev_name == 'RDM6300': | ||
self.devs.append(Rdm6300Reader()) | ||
elif dev_name == 'PN532': | ||
self.devs.append(Pn532Reader()) | ||
else: | ||
try: | ||
usb_reader = UsbReader(device) | ||
self.devs.append(usb_reader) | ||
except IndexError: | ||
sys.exit('Could not find the device %s.\n Make sure it is connected' % dev_name) | ||
break | ||
|
||
def readCard(self): | ||
que = SimpleQueue() | ||
threads_list = list() | ||
|
||
for dev in self.devs: | ||
t = multiprocessing.Process(target=lambda q: q.put(dev.readCard()), args=(que,)) | ||
t.start() | ||
threads_list.append(t) | ||
|
||
found_result = False | ||
while not found_result: | ||
for process in threads_list: | ||
process.join(0.001) | ||
if not process.is_alive(): | ||
found_result = True | ||
break | ||
|
||
for process in threads_list: | ||
process.terminate() | ||
|
||
return que.get() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.