stm32-fmt-code/access_control_python/main.py

243 lines
9.8 KiB
Python

import cv2
import threading
import time
import face_processing as fp
from access_control_mqtt import access_control
from database import Database, Student, Parent
from display import Display
from stm32 import stm32_distance
SERIAL_PORT_DISPLAY = "/dev/serial0"
CAMERA_INDEX = 0
display = Display(SERIAL_PORT_DISPLAY)
cam = cv2.VideoCapture(CAMERA_INDEX)
actrl = access_control()
db = Database()
global img
global frame_ready
frame_ready = False
def read_webcam():
global img
global frame_ready
while True:
ret, img = cam.read()
frame_ready = True
'''
display.set_page("student")
display.set_string("msg.txt","Door Open")
'''
student_info = None
parent_info = None
faces = None
threading.Thread(target=read_webcam).start()
def door_open():
actrl.unlock_door()
for i in range(10):
display.set_string("msg.txt",f'Door will close in {10-i}')
time.sleep(1)
i = 5
#TODO Check if door close, lock
alarm_active: bool = False
display.set_page("leftopen")
while(i>=0):
if (not actrl.get_door_state() and not alarm_active): # False door is left open
display.set_string("msg.txt","Door is left open, Alram in {} sec".format(i))
time.sleep(1)
i -= 1
if i == 0:
actrl.activate_alarm()
display.set_string("msg.txt","Alarm Active, Please Close Door.")
#actrl.activate_LED_alarm()
elif(actrl.get_door_state()):
actrl.lock_door()
display.set_page("scan")
should_restart = True
break
#display.set_page("scan")
SD = stm32_distance("/dev/serial/by-id/usb-STMicroelectronics_STM32_STLink_066DFF505282494867205639-if02")
#start_time = time.perf_counter()
flag: bool = False
"""
while True:
state = round((perf_counter())%1)
if(flag!=state):
flag = state
print(f"change to : {state}")
print(state)
delay(0.05)
"""
while True:
while not frame_ready:
time.sleep(1)
should_restart = True
distance = SD.get_distance()
print(distance)
state = distance < 800
if state!= flag:
flag = state
if(state):
display.set_string("msg.txt","Scanning")
else:
display.set_page("scan")
if (state): # Scan state
while should_restart:
#Try to identify face
should_restart = False
#if actrl.get_scan_state():
if(True):
#print("SCAN ACTIVE!")
#display.set_string("msg.txt","Scanning")
faces = fp.identify_face(img, target_condidence=0.6) ## Scan student face
if(len(faces)==1):
#print("faces == 1")
facefile = faces[0]['name'] ## File name
print(facefile)
student_info = db.get_student_info(facefile)## Check is it student?
parent_info = db.get_parent_info(facefile)
if(student_info!=None): #is student, request another scan for parent
print("Find student info")
#db.log_access_student_file()
parent_info = None
display.set_page("student")
#display.set_string("msg.txt",f'Scan parent face ({10-i})')
display.set_string("name_std.txt", f'Name: {student_info.name}')
display.set_string("surname_std.txt",f'Surname: {student_info.surname}')
display.set_string("id_std.txt", f'ID: {str(student_info.id)}')
"""
parent_face = fp.identify_face(img, target_condidence=0.6)
parent_info = db.get_parent_info(parent_face)"""
#DONE TODO Fill in student info Resolve
print(student_info)
i = 0
start_time = time.perf_counter()
while(time.perf_counter()-start_time < 10):
parent_face = fp.identify_face(img, target_condidence=0.6)
if (len(parent_face)!= 0):
parent_facefile = parent_face[0]['name']
parent_info = db.get_parent_info(parent_facefile)
if(parent_info != None): # Identified parent
if(db.check_relationship(student_info,parent_info)): # Check if the detected parent is right for the detected student.
print("Relation is OKAY")
#DONE TODO Log Access STDw/P
db.log_access_student_with_parent(student_info, student_info)
#DONE TODO write parrent info to display
display.set_string("name_pt.txt", f'Name: {parent_info.name}')
display.set_string("surname_pt.txt", f'Surname: {parent_info.surname}')
display.set_string("id_pt.txt", f'ID: {parent_info.id}')
actrl.unlock_door() # Door open
display.set_string("msg.txt","Get your kid")
#DONE TODO Send timer to display
door_open()
"""
for i in range(10):
display.set_string("msg.txt",f'Door will close in {10-i}')
time.sleep(1)
i = 5
#TODO Check if door close, lock
alarm_active: bool = False
while(i>=0):
if (not actrl.get_door_state() and not alarm_active): # False door is left open
display.set_string("msg.txt","Door is left open, Alram in {} sec".format(i))
time.sleep(1)
i -= 1
if i == 0:
actrl.activate_LED_alarm()
alarm_active = True
elif(actrl.get_door_state()):
actrl.lock_door()
display.set_page("scan")
should_restart = True
break
display.set_page("scan")
"""
else:
display.set_page("scan")
display.set_string("msg.txt","Wrong parent. \t Try Again")
time.sleep(1)
should_restart = True
break
#TODO Try again does not try again
elif(len(parent_face) == 0):
time.sleep(1)
display.set_string("msg.txt",f'Scan parent face ({10-i})')
i += 1
else:
pass
display.set_page("scan")
elif(parent_info!=None): #is parent, open door
#parent_facefile = faces[0]['name']
#parent_info = db.get_parent_info(parent_facefile)
#if(parent_info!= None):
print("Find parent info")
display.set_page("prt_wo_stu")
display.set_string("name_pt.txt", f'Name: {parent_info.name}')
display.set_string("surname_pt.txt", f'Surname: {parent_info.surname}')
display.set_string("id_pt.txt", f'ID: {parent_info.id}')
db.log_access_parent(parent_info)
door_open()
pass
elif (len(faces)>1):
#More than one people, error.
print("more than one people. \t try again")
display.set_string("msg.txt","More than one people. \t try again")
time.sleep(2)
pass
#print("DONE")
else:
display.set_string("msg.txt","Move your face closer to the scanner")
print("Scan inactivate!!")
'''
#is student, request another scan for parent
parent_face = fp.identify_face(img, target_condidence=0.6)
if(len(faces)==1):
parent_info = db.get_parent_info(faces[0]['name'])
if(parent_info!=None):
if(db.check_relationship(student_info,parent_info)):
#Student is under parent, open door.
pass
else:
#Wrong Parent, retry.
pass
else:
#Not a parent, retry
pass
'''