# 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