123 lines
4.3 KiB
Python
123 lines
4.3 KiB
Python
|
# Setting up raspi for card reader
|
||
|
# https://pimylifeup.com/raspberry-pi-rfid-rc522/
|
||
|
#
|
||
|
from database import *
|
||
|
import time
|
||
|
|
||
|
import RPi.GPIO as GPIO
|
||
|
from mfrc522 import SimpleMFRC522
|
||
|
|
||
|
class DoorLock():
|
||
|
def __init__(self):
|
||
|
# initialize card reader
|
||
|
self.reader = SimpleMFRC522()
|
||
|
|
||
|
def increment(self, counter):
|
||
|
# increment counter and send it to card
|
||
|
counter += 1
|
||
|
data_new = str(counter)
|
||
|
|
||
|
self.reader.write(data_new)
|
||
|
|
||
|
# check if counter was updated successfully
|
||
|
_, text = self.reader.read()
|
||
|
try:
|
||
|
counter_new = int(text)
|
||
|
except ValueError:
|
||
|
return False
|
||
|
return counter == counter_new
|
||
|
|
||
|
def check_authorization(self, reader_id, counter):
|
||
|
# open database
|
||
|
conn = create_connection(database)
|
||
|
|
||
|
# check if id is in the database
|
||
|
with conn:
|
||
|
users = select_all_users(conn)
|
||
|
|
||
|
for user in users:
|
||
|
db_id = user[0]
|
||
|
name = user[1]
|
||
|
user_card_id = user[2]
|
||
|
user_counter = user[3]
|
||
|
if reader_id == user_card_id:
|
||
|
# check if use counter on the card matches counter in the database
|
||
|
# if counter is different -> assume the card has been cloned
|
||
|
if counter == user_counter:
|
||
|
print("user {} with card_id {} authorized".format(name, hex(reader_id)))
|
||
|
return True, db_id
|
||
|
else:
|
||
|
print("error: counter does not match! please investigate!")
|
||
|
|
||
|
# if no match was found in the database: deny entry
|
||
|
print("You shall not pass!")
|
||
|
print("could not authorize card_id {}".format(reader_id))
|
||
|
return False, None
|
||
|
|
||
|
|
||
|
def unlock_door(self):
|
||
|
# TODO send command to open door lock
|
||
|
print("Unlocking door!\n\n")
|
||
|
|
||
|
def release_the_kraken(self):
|
||
|
# TODO notify that authentication failed
|
||
|
# not implemented yet
|
||
|
print("Release the Kraken!")
|
||
|
|
||
|
def run_authorization(self):
|
||
|
try:
|
||
|
while True:
|
||
|
print("Hold card before reader..")
|
||
|
uid, data = self.reader.read()
|
||
|
|
||
|
print("data = ", data)
|
||
|
#counter = int.from_bytes(data, byteorder='big')
|
||
|
try:
|
||
|
counter = int(data)
|
||
|
except ValueError:
|
||
|
print("error: data on the card could not be converted")
|
||
|
counter = None
|
||
|
|
||
|
if counter is not None:
|
||
|
print("card read: \n uid = {}\ncounter = {}\n".format(hex(uid), counter))
|
||
|
authorized, db_id = self.check_authorization(uid, counter)
|
||
|
|
||
|
if authorized:
|
||
|
# increment use counter on the card
|
||
|
increment_status = self.increment(counter)
|
||
|
|
||
|
if increment_status:
|
||
|
# update the counter and the time of last access in the database
|
||
|
# open database
|
||
|
conn = create_connection(database)
|
||
|
increment_counter(conn, db_id)
|
||
|
|
||
|
self.unlock_door()
|
||
|
else:
|
||
|
# if we cannot increment the counter on the card (e.g. because the card was removed too quickly)
|
||
|
# we do not let the user in even though authentication was correct -> try again
|
||
|
print("increment failed!")
|
||
|
else:
|
||
|
print("authentication failed")
|
||
|
self.release_the_kraken()
|
||
|
time.sleep(1.5)
|
||
|
finally:
|
||
|
#GPIO.cleanup()
|
||
|
pass
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
# create database with some users
|
||
|
# conn = setup_db()
|
||
|
# with conn:
|
||
|
# create_user(conn, 'Simon', 4225799947, 0, str(datetime.utcnow()), str(datetime.utcnow()))
|
||
|
# create_user(conn, 'Valentin', 154921302, 0, str(datetime.utcnow()), str(datetime.utcnow()))
|
||
|
# users = select_all_users(conn)
|
||
|
|
||
|
doors_of_durin = DoorLock()
|
||
|
|
||
|
data = bytearray([0]*16)
|
||
|
#data = '0'
|
||
|
#write_success = doors_of_durin.reader.write(data)
|
||
|
doors_of_durin.run_authorization()
|
||
|
pass
|