Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 4862

Assistive technology and accessibility • Small RFID 125KHZ (RDM6300) Attendance and Access Control

$
0
0
Hello Everyone, I have you are well.

I have a small office, and I wanted to create a small RFID based attendance system and Access Control for my staff.

I am sharing the code below, everything is working fine But, but there is an issue with the unlocking.

I am using Pi Zero2W, which works well. No issues with that. When I run the python file and I scan the RFID card once, it does record the attendance but it records it many times after scanning, even if the card is not in front of it and (I have attached a magnetic lock with that) it keeps locking and unlocking several times.

Code:

import sqlite3from openpyxl import Workbook, load_workbookfrom datetime import datetimeimport timeimport RPi.GPIO as GPIOimport socketimport rdm6300# Get the hostname dynamicallyHOSTNAME = socket.gethostname()print("Hostname:", HOSTNAME)# Setup GPIOGPIO.setmode(GPIO.BOARD)GPIO.setwarnings(False)Lock = 37Button = 36  # Use physical pin number 11 for GPIO 16GPIO.setup(Lock, GPIO.OUT)GPIO.setup(Button, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)  # Set up pin 11 as input with pull-down resistorGPIO.output(Lock, GPIO.HIGH)# SQLite database setupdef init_db():    conn = sqlite3.connect('attendance.db')    c = conn.cursor()    c.execute('''CREATE TABLE IF NOT EXISTS Employees (                     ID INTEGER PRIMARY KEY,                     name TEXT,                     team_name TEXT,                     card_id INTEGER UNIQUE,                     status TEXT CHECK(status IN ('active', 'disabled')) DEFAULT 'active')''')    c.execute('''CREATE TABLE IF NOT EXISTS Location (                     LocationID INTEGER PRIMARY KEY,                     LocationName TEXT)''')    c.execute('''CREATE TABLE IF NOT EXISTS Site (                     SiteID INTEGER PRIMARY KEY,                     SiteName TEXT,                     LocationID INTEGER,                     FOREIGN KEY (LocationID) REFERENCES Location(LocationID))''')    c.execute('''CREATE TABLE IF NOT EXISTS Door (                     DoorID INTEGER PRIMARY KEY,                     DoorName TEXT,                     SiteID INTEGER,                     FOREIGN KEY (SiteID) REFERENCES Site(SiteID))''')    c.execute('''CREATE TABLE IF NOT EXISTS EmployeeLocation (                     EmployeeID INTEGER,                     LocationID INTEGER,                     StartTime TEXT,                     EndTime TEXT,                     PRIMARY KEY (EmployeeID, LocationID),                     FOREIGN KEY (EmployeeID) REFERENCES Employees(ID),                     FOREIGN KEY (LocationID) REFERENCES Location(LocationID))''')    c.execute('''CREATE TABLE IF NOT EXISTS EmployeeSite (                     EmployeeID INTEGER,                     SiteID INTEGER,                     StartTime TEXT,                     EndTime TEXT,                     PRIMARY KEY (EmployeeID, SiteID),                     FOREIGN KEY (EmployeeID) REFERENCES Employees(ID),                     FOREIGN KEY (SiteID) REFERENCES Site(SiteID))''')    c.execute('''CREATE TABLE IF NOT EXISTS EmployeeDoor (                     EmployeeID INTEGER,                     DoorID INTEGER,                     StartTime TEXT,                     EndTime TEXT,                     PRIMARY KEY (EmployeeID, DoorID),                     FOREIGN KEY (EmployeeID) REFERENCES Employees(ID),                     FOREIGN KEY (DoorID) REFERENCES Door(DoorID))''')    conn.commit()    return connconn = init_db()def is_access_allowed(employee):    return employee[3] == 'active'def setup_excel():    excel_file_name = 'attendance_excel.xlsx'    try:        wb = load_workbook(excel_file_name)    except FileNotFoundError:        wb = Workbook()    sheet_name = str(datetime.now().date())    if sheet_name not in wb.sheetnames:        sheet = wb.create_sheet(title=sheet_name)        sheet.append(['Full Name', 'Personnel ID', 'Date and Time', 'Location'])    else:        sheet = wb[sheet_name]    wb.save(excel_file_name)    return wb, sheetdef get_employee_by_card_id(card_id):    c = conn.cursor()    c.execute('''SELECT ID, name, card_id, status                 FROM Employees                 WHERE card_id = ?''', (card_id,))    return c.fetchone()def is_employee_allowed_at_door(employee_id, door_name, current_time):    c = conn.cursor()    c.execute('''SELECT ed.StartTime, ed.EndTime                 FROM EmployeeDoor ed                 JOIN Door d ON ed.DoorID = d.DoorID                 WHERE ed.EmployeeID = ? AND d.DoorName = ?''', (employee_id, door_name))    row = c.fetchone()    if row:        start_time, end_time = row        start_time = datetime.strptime(start_time, '%H:%M').time()        end_time = datetime.strptime(end_time, '%H:%M').time()        return start_time <= current_time <= end_time    return Nonedef button_callback(channel):    print("Button pressed, deactivating relay for 5 seconds.")    GPIO.output(Lock, GPIO.LOW)    time.sleep(5)    GPIO.output(Lock, GPIO.HIGH)    print("Relay reactivated.")def record_attendance(wb, sheet):    GPIO.output(Lock, True)    excel_file_name = 'attendance_excel.xlsx'    rfid_reader = rdm6300.Reader('/dev/ttyS0')    last_access_time = None  # To track the last access time    last_card_id = None  # To track the last scanned card ID    lockout_period = False  # To track if the system is in lockout period    while True:        try:            if not lockout_period:                print('Scan Your Card')                card = rfid_reader.read()  # Blocking call to read the card                if card:                    card_id = card.value                    now = datetime.now().strftime("%d-%m-%Y %I:%M:%S %p")                    current_time = datetime.now().time()                    print('Card ID: {}'.format(card_id))                    print('Time of Scan: {}'.format(now))                                        # Check if the current card is the same as the last card                    if card_id != last_card_id or (datetime.now() - last_access_time).total_seconds() >= 5:                        last_card_id = card_id                        last_access_time = datetime.now()                                                employee = get_employee_by_card_id(card_id)                        if employee:                            print('Employee details:', employee)                            if is_access_allowed(employee):                                allowed_time_range = is_employee_allowed_at_door(employee[0], HOSTNAME, current_time)                                if allowed_time_range is not None:                                    if allowed_time_range:                                        print("Access allowed. Opening Door")                                        GPIO.output(Lock, GPIO.LOW)  # Deactivate the lock                                        lockout_period = True  # Enter lockout period                                        sheet.append([employee[1], employee[2], now, HOSTNAME])                                        wb.save(excel_file_name)                                        # Wait until the door is closed and then reset lockout_period                                        while (datetime.now() - last_access_time).total_seconds() < 5:                                            time.sleep(0.1)  # Periodically check if 5 seconds have passed                                        GPIO.output(Lock, GPIO.HIGH)  # Reactivate the lock                                        lockout_period = False  # Reset lockout period                                    else:                                        print("Access not allowed at this time")                                else:                                    print("Access not allowed at this door")                            else:                                print("Employee is disabled. Attendance not recorded.")                        else:                            print('Employee not found')                            time.sleep(1)            else:                time.sleep(0.1)  # During lockout period, check periodically        except Exception as e:            print("Error during attendance recording: {}".format(e))        except KeyboardInterrupt:            print("Script terminated by user.")            break        finally:            GPIO.output(Lock, GPIO.HIGH)            time.sleep(0.1)if __name__ == "__main__":    try:        wb = load_workbook('attendance_excel.xlsx')    except FileNotFoundError:        wb = Workbook()    sheet_name = str(datetime.now().date())    if sheet_name not in wb.sheetnames:        sheet = wb.create_sheet(title=sheet_name)        sheet.append(['Full Name', 'Personnel ID', 'Date and Time', 'Location'])    else:        sheet = wb[sheet_name]    try:        # Add event detection for the button press        GPIO.add_event_detect(Button, GPIO.RISING, callback=button_callback, bouncetime=200)                record_attendance(wb, sheet)    except KeyboardInterrupt:        print("Script terminated by user.")    finally:        conn.close()        GPIO.cleanup()
I am not sure what is the issue; sometimes I feel that it is interference issue, but I am not sure. If anyone wants, I can also send the pictures of the actual thing I built. I have attached a picture, this is the rdm633 i am using (reference picture). Can anyone please guide me ?
Screenshot 2024-11-11 162832.jpg

Statistics: Posted by safiullahtariq — Mon Nov 11, 2024 11:32 am



Viewing all articles
Browse latest Browse all 4862

Trending Articles