top of page

# USAGE
# python3 train_mask_detector.py --dataset dataset
# import the necessary packages
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Input
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras.utils import to_categorical
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import os
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True,
help="path to input dataset")
ap.add_argument("-p", "--plot", type=str, default="plot.png",
help="path to output loss/accuracy plot")
ap.add_argument("-m", "--model", type=str,
default="mask_detector.model",
help="path to output face mask detector model")
args = vars(ap.parse_args())
# initialize the initial learning rate, number of epochs to train for,
# and batch size
INIT_LR = 1e-4
EPOCHS = 20
BS = 32
# grab the list of images in our dataset directory, then initialize
# the list of data (i.e., images) and class images
print("[INFO] loading images...")
imagePaths = list(paths.list_images(args["dataset"]))
data = []
labels = []
# loop over the image paths
for imagePath in imagePaths:
# extract the class label from the filename
label = imagePath.split(os.path.sep)[-2]
# load the input image (224x224) and preprocess it
image = load_img(imagePath, target_size=(224, 224))
image = img_to_array(image)
image = preprocess_input(image)
# update the data and labels lists, respectively
data.append(image)
labels.append(label)
# convert the data and labels to NumPy arrays
data = np.array(data, dtype="float32")
labels = np.array(labels)
# perform one-hot encoding on the labels
lb = LabelBinarizer()
labels = lb.fit_transform(labels)
labels = to_categorical(labels)
# partition the data into training and testing splits using 75% of
# the data for training and the remaining 25% for testing
(trainX, testX, trainY, testY) = train_test_split(data, labels,
test_size=0.20, stratify=labels, random_state=42)
# construct the training image generator for data augmentation
aug = ImageDataGenerator(
rotation_range=20,
zoom_range=0.15,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.15,
horizontal_flip=True,
fill_mode="nearest")
# load the MobileNetV2 network, ensuring the head FC layer sets are
# left off
baseModel = MobileNetV2(weights="imagenet", include_top=False,
input_tensor=Input(shape=(224, 224, 3)))
# construct the head of the model that will be placed on top of the
# the base model
headModel = baseModel.output
headModel = AveragePooling2D(pool_size=(7, 7))(headModel)
headModel = Flatten(name="flatten")(headModel)
headModel = Dense(128, activation="relu")(headModel)
headModel = Dropout(0.5)(headModel)
headModel = Dense(2, activation="softmax")(headModel)
# place the head FC model on top of the base model (this will become
# the actual model we will train)
model = Model(inputs=baseModel.input, outputs=headModel)
# loop over all layers in the base model and freeze them so they will
# *not* be updated during the first training process
for layer in baseModel.layers:
layer.trainable = False
# compile our model
print("[INFO] compiling model...")
opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="binary_crossentropy", optimizer=opt,
metrics=["accuracy"])
# train the head of the network
print("[INFO] training head...")
H = model.fit(
aug.flow(trainX, trainY, batch_size=BS),
steps_per_epoch=len(trainX) // BS,
validation_data=(testX, testY),
validation_steps=len(testX) // BS,
epochs=EPOCHS)
# make predictions on the testing set
print("[INFO] evaluating network...")
predIdxs = model.predict(testX, batch_size=BS)
# for each image in the testing set we need to find the index of the
# label with corresponding largest predicted probability
predIdxs = np.argmax(predIdxs, axis=1)
# show a nicely formatted classification report
print(classification_report(testY.argmax(axis=1), predIdxs,
target_names=lb.classes_))
# serialize the model to disk
print("[INFO] saving mask detector model...")
model.save(args["model"], save_format="h5")
# plot the training loss and accuracy
N = EPOCHS
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, N), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, N), H.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, N), H.history["accuracy"], label="train_accuracy")
plt.plot(np.arange(0, N), H.history["val_accuracy"], label="val_accuracy")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.savefig(args["plot"])
import cv2
name = 'with_mask' #write to the with_mask folder
cam = cv2.VideoCapture(0)
cv2.namedWindow("press space to take a photo", cv2.WINDOW_NORMAL)
cv2.resizeWindow("press space to take a photo", 500, 300)
img_counter = 0
while True:
ret, frame = cam.read()
if not ret:
print("failed to grab frame")
break
cv2.imshow("press space to take a photo", frame)
k = cv2.waitKey(1)
if k%256 == 27:
# ESC pressed
print("Escape hit, closing...")
break
elif k%256 == 32:
# SPACE pressed
img_name = "dataset/"+ name +"/image_{}.jpg".format(img_counter)
cv2.imwrite(img_name, frame)
print("{} written!".format(img_name))
img_counter += 1
cam.release()
cv2.destroyAllWindows()
import cv2
name = 'without_mask' #write to the without_mask folder
cam = cv2.VideoCapture(0)
cv2.namedWindow("press space to take a photo", cv2.WINDOW_NORMAL)
cv2.resizeWindow("press space to take a photo", 500, 300)
img_counter = 0
while True:
ret, frame = cam.read()
if not ret:
print("failed to grab frame")
break
cv2.imshow("press space to take a photo", frame)
k = cv2.waitKey(1)
if k%256 == 27:
# ESC pressed
print("Escape hit, closing...")
break
elif k%256 == 32:
# SPACE pressed
img_name = "dataset/"+ name +"/image_{}.jpg".format(img_counter)
cv2.imwrite(img_name, frame)
print("{} written!".format(img_name))
img_counter += 1
cam.release()
cv2.destroyAllWindows()
# USAGE
# python3 detect_mask_webcam.py
# import the necessary packages
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.models import load_model
from imutils.video import VideoStream
import numpy as np
import argparse
import imutils
import time
import cv2
import os
from time import sleep
#This imports the ServoKit class from Adafruit. They are the manufacture of this HAT that we are using.
from adafruit_servokit import ServoKit
#This is to specify how many channels the Raspberry Pi HAT has. This HAT has 16.
kit = ServoKit(channels=16)
#Channel 2 is Y-axis
#Channel 1 is X-axis
kit.servo[2].angle = 40 # 60 degrees is centered for Y-axis.
kit.servo[1].angle = 70 # 70 degrees is centered for X-axis.
def detect_and_predict_mask(frame, faceNet, maskNet, args):
#grab the dimensions of the frame and then construct a blob
# from it
(h, w) = frame.shape[:2]
blob = cv2.dnn.blobFromImage(frame, 1.0, (300, 300),
(104.0, 177.0, 123.0))
# pass the blob through the network and obtain the face detections
faceNet.setInput(blob)
detections = faceNet.forward()
# initialize our list of faces, their corresponding locations,
# and the list of predictions from our face mask network
faces = []
locs = []
preds = []
# loop over the detections
for i in range(0, detections.shape[2]):
# extract the confidence (i.e., probability) associated with
# the detection
confidence = detections[0, 0, i, 2]
# filter out weak detections by ensuring the confidence is
# greater than the minimum confidence
if confidence > args["confidence"]:
# compute the (x, y)-coordinates of the bounding box for
# the object
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
# ensure the bounding boxes fall within the dimensions of
# the frame
(startX, startY) = (max(0, startX), max(0, startY))
(endX, endY) = (min(w - 1, endX), min(h - 1, endY))
# extract the face ROI, convert it from BGR to RGB channel
# ordering, resize it to 224x224, and preprocess it
face = frame[startY:endY, startX:endX]
face = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)
face = cv2.resize(face, (224, 224))
face = img_to_array(face)
face = preprocess_input(face)
# add the face and bounding boxes to their respective
# lists
faces.append(face)
locs.append((startX, startY, endX, endY))
if len(faces) == 1:
move_camera(w, h, startX, startY, endX, endY)
# only make a predictions if at least one face was detected
if len(faces) > 0:
# for faster inference we'll make batch predictions on *all*
# faces at the same time rather than one-by-one predictions
# in the above `for` loop
faces = np.array(faces, dtype="float32")
preds = maskNet.predict(faces, batch_size=32)
if len(faces) == 0: #Moves cameras back to home position when no face is detected after 5 seconds
sleep(5)
kit.servo[2].angle = 40 # 60 degrees is centered for Y-axis.
kit.servo[1].angle = 70 # 70 degrees is centered for X-axis.
# return a 2-tuple of the face locations and their corresponding
# locations
return (locs, preds)
def maskcamera(covidConditions):
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-f", "--face", type=str,
default="face_detector",
help="path to face detector model directory")
ap.add_argument("-m", "--model", type=str,
default="mask_detector.model",
help="path to trained face mask detector model")
ap.add_argument("-c", "--confidence", type=float, default=0.5,
help="minimum probability to filter weak detections")
args = vars(ap.parse_args())
# load our serialized face detector model from disk
print("[INFO] loading face detector model...")
prototxtPath = os.path.sep.join([args["face"], "deploy.prototxt"])
weightsPath = os.path.sep.join([args["face"],
"res10_300x300_ssd_iter_140000.caffemodel"])
faceNet = cv2.dnn.readNet(prototxtPath, weightsPath)
# load the face mask detector model from disk
print("[INFO] loading face mask detector model...")
maskNet = load_model(args["model"])
# initialize the video stream and allow the camera sensor to warm up
print("[INFO] starting video stream...")
vs = VideoStream(src=0).start()
time.sleep(2.0)
# loop over the frames from the video stream
while True:
try:
# grab the frame from the threaded video stream and resize it
# to have a maximum width of 400 pixels
frame = vs.read()
frame = imutils.resize(frame, width=500)
# detect faces in the frame and determine if they are wearing a
# face mask or not
(locs, preds) = detect_and_predict_mask(frame, faceNet, maskNet, args)
# loop over the detected face locations and their corresponding
# locations
for (box, pred) in zip(locs, preds):
# unpack the bounding box and predictions
(startX, startY, endX, endY) = box
(mask, withoutMask) = pred
# determine the class label and color we'll use to draw
# the bounding box and text
if mask > withoutMask:
label = "Face Mask Detected"
color = (0, 255, 0)
covidConditions["mask"] = True
print("Mask detected")
else:
label = "No Face Mask Detected"
color = (0, 0, 255)
covidConditions["mask"] = False
print("No Face Mask detected")
# display the label and bounding box rectangle on the output
# frame
cv2.putText(frame, label, (startX-50, startY - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2)
cv2.rectangle(frame, (startX, startY), (endX, endY), color, 2)
# show the output frame
cv2.imshow("Face Mask Detector", frame)
key = cv2.waitKey(1) & 0xFF
# if the `q` key was pressed, break from the loop
if key == ord("q"):
break
#Adding an exception to catch the error (cvtColor) to prevent the program from stopping
except Exception as e:
print(e)
pass
# do a bit of cleanup
cv2.destroyAllWindows()
vs.stop()
def move_camera(framex, framey, startX, startY, endX, endY):
centerx = framex/2
centery = framey/2
center_facex = (startX + endX)/2
center_facey = (startY + endY)/2
#Defining the tolerance of the servo angles
if abs(centerx - center_facex) >= 30:
if centerx < center_facex:
if kit.servo[1].angle >= 5:
print(kit.servo[1].angle)
print("X")
kit.servo[1].angle -= 5
else:
print("ATTEMPTED TO MOVE TO THE RIGHT, BUT")
print(kit.servo[1].angle)
print("IS TOO SHALLOW")
elif centerx > center_facex:
if kit.servo[1].angle <= 175:
print(kit.servo[1].angle)
print("X")
kit.servo[1].angle += 5
else:
print("ATTEMPTED TO MOVE TO THE LEFT, BUT")
print(kit.servo[1].angle)
print("IS TOO SHALLOW")
if abs(centery - center_facey) >= 30:
if centery > center_facey:
if kit.servo[2].angle >= 5:
print(kit.servo[2].angle)
print("Y")
kit.servo[2].angle -= 5
else:
print("ATTEMPTED TO MOVE UP,BUT")
print(kit.servo[2].angle)
print("IS TOO SHALLOW")
elif centery < center_facey:
if kit.servo[2].angle <=175:
print(kit.servo[2].angle)
print("Y")
kit.servo[2].angle += 5
else:
print("ATTEMPTED TO MOVE DOWN, BUT")
print(kit.servo[2].angle)
print("IS TOO SHALLOW")
#covidConditions = {"mask": False}
#maskcamera(covidConditions)
##########################################
# MLX90640 Thermal Camera w Raspberry Pi
# -- 2Hz Sampling with Simple Routine
##########################################
#
import time,board,busio
import numpy as np
import adafruit_mlx90640
import matplotlib.pyplot as plt
def tempcamera(covidConditions):
print("Initializing MLX90640")
i2c = busio.I2C(board.SCL, board.SDA, frequency=80000) #Setup I2C
mlx = adafruit_mlx90640.MLX90640(i2c) #Begin MLX90640 with I2C comm
mlx.refresh_rate = adafruit_mlx90640.RefreshRate.REFRESH_2_HZ #Set refresh rate
mlx_shape = (24,32)
print("Initialized")
#Setup the figure for plotting
plt.ion() #Enables interactive plotting
fig,ax = plt.subplots(figsize=(12,7))
therm1 = ax.imshow(np.zeros(mlx_shape),vmin=0,vmax=60) #Start plot with zeros
cbar = fig.colorbar(therm1) #Setup colorbar for temps
cbar.set_label('Temperature [$^{\circ}$C]',fontsize=14) #Colorbar label
frame = np.zeros((24*32,)) #Setup array for storing all 768 temperatures
t_array = []
print("Starting loop")
while True:
t1 = time.monotonic()
try:
mlx.getFrame(frame) #Read MLX temperatures into frame var
data_array = (np.reshape(frame,mlx_shape)) #Reshape to 24x32
therm1.set_data(np.fliplr(data_array)) #Flip left to right
therm1.set_clim(vmin=np.min(data_array),vmax=np.max(data_array)*1.079) # set bounds
cbar.update_normal(therm1) #Update colorbar range
plt.title(f"Max Temp: {np.max(data_array)*1.079:.1f}C")
plt.pause(0.001) #Required
#fig.savefig('mlx90640_test_fliplr.png',dpi=300,facecolor='#FCFCFC', bbox_inches='tight') # comment out to speed up
t_array.append(time.monotonic()-t1)
#Multiplied by a factor of 1.079 to increase reading accuracy
# This is set for a max of 38 degrees centigrade. 38C=100.4F which at
#100.4, you are considered to have a fever.
if (np.max(data_array)*1.079 < 38):
covidConditions["thermal"] = True
#For us to know if the conditions are correct or not
print('Temperature Below 38C')
else:
covidConditions["thermal"] = False
#For us to know if the conditions are correct or not
print('Temperature Above 38C')
print('Sample Rate: {0:2.1f}fps'.format(len(t_array)/np.sum(t_array)))
except ValueError:
continue # if error, just read again
#covidConditions = {"thermal": False}
#tempcamera(covidConditions)
from tkinter import *
from tkinter import messagebox
from tkinter import font as tkFont
from vidstream import AudioSender
from vidstream import AudioReceiver
from time import *
import threading
import vlc
## These are different types of windows that can be used
#showinfo, showwarning, showerror, askquestion, askokcancel, askyesno
global fD
fD = vlc.MediaPlayer("/home/charlie/Desktop/Outside_RaspberryPi/frontdesk.mp3")
global q1
q1 = vlc.MediaPlayer("/home/charlie/Desktop/Outside_RaspberryPi/q1.mp3")
global q2
q2 = vlc.MediaPlayer("/home/charlie/Desktop/Outside_RaspberryPi/q2.mp3")
global q3
q3 = vlc.MediaPlayer("/home/charlie/Desktop/Outside_RaspberryPi/q3.mp3")
global q4
q4 = vlc.MediaPlayer("/home/charlie/Desktop/Outside_RaspberryPi/q4.mp3")
global aT
aT = vlc.MediaPlayer("/home/charlie/Desktop/Outside_RaspberryPi/alltimes.mp3")
global pP
pP = vlc.MediaPlayer("/home/charlie/Desktop/Outside_RaspberryPi/pP.mp3")
global cH
cH = vlc.MediaPlayer("/home/charlie/Desktop/Outside_RaspberryPi/clickh.mp3")
def popup(covidConditions, root):
##Need to define response
q1.play()
response = messagebox.askyesno("Questionnaire Window",
"Have you traveled domestically or internationally in the last 30 days?")
if response == 1:
q1.stop()
fD.play()
messagebox.showwarning("Questionnaire Response","Please Contact Front Desk Staff")
#messagebox.showwarning("Questionnaire Response","Please Contact Front Desk Staff",command = lambda: 'frontdesk')
covidConditions["questions"] = False
fD.stop()
else:
q1.stop()
q2.play()
response1 = messagebox.askyesno("Questionnaire Window", "Are you waiting for the results of a COVID-19 test?")
if response1 == 1:
q2.stop()
fD.play()
messagebox.showwarning("Questionnaire Response", "Please Contact Front Desk Staff")
covidConditions["questions"] = False
fD.stop()
else:
q2.stop()
q3.play()
response2 = messagebox.askyesno("Questionnaire Window", "Are you showing any symptoms of COVID-19?")
if response2 == 1:
q3.stop()
fD.play()
messagebox.showwarning("Questionnaire Response", "Please Contact Front Desk Staff")
covidConditions["questions"] = False
fD.stop()
else:
q3.stop()
q4.play()
response3 = messagebox.askyesno("Questionnaire Window", "Were you in close contact with someone known to have been infected with COVID-19?")
if response3 == 1:
q4.stop()
fD.play()
messagebox.showwarning("Questionnaire Response", "Please Contact Front Desk Staff")
covidConditions["questions"] = False
fD.stop()
else:
q4.stop()
aT.play()
response4 = messagebox.askyesno("Questionnaire Window", "In accordance with healthcare mandates,masking is required for entrance into this facility during your stay. Do you agree to these terms?")
if response4 == 0:
aT.stop()
fD.play()
messagebox.showwarning("Questionnaire Response", "Please Contact Front Desk Staff")
covidConditions["questions"] = False
fD.stop()
else:
aT.stop()
pP.play()
fD.stop()
enter = messagebox.showinfo("Questionnaire Response", "Please Proceed To Enter The Building")
covidConditions["questions"] = True
receiver = AudioReceiver('169.254.176.185', 9999) #This is the Inside Raspberry Pi (Pi4)
sender = AudioSender('169.254.167.227', 5555) # This is the Outside Raspberry Pi (Pi3)
def start_call():
receiver.start_server()
sender.start_stream()
def end_call():
receiver.stop_server()
sender.stop_stream()
def clickh():
cH = vlc.MediaPlayer("/home/charlie/Desktop/Outside_RaspberryPi/clickh.mp3")
cH.play()
fD.stop()
#lambda is used here to prevent the threading from starting immediately without the button press.
#It calls the thread but does not start it yet.
def CovidQuestionnaire(covidConditions):
root = Tk()
#MAKES THIS FULLSCREEN WITH OUT THE ABILITY TO EXIT
root.attributes('-fullscreen',True)
label = Label(root, text = "Please stand on the green line then Press Click Here To Begin.\n \n If you need to speak to someone, please press 'Start Call'",
height=8,width=100, command = clickh()).pack()
click = Button(root,text= "Click Here To Begin",height=8,width=100, bg='#FA8128',fg='black',
font= ('helvetica',11,'bold'),command=lambda: popup(covidConditions,root)).pack()
start = Button(root,text= "Start Call", fg='#00CC00',height=5,width=100,
font= ('helvetica',11,'bold'), command=lambda:start_call()).pack()
end = Button(root,text= "End Call", fg='#FF4D4D',height=5,width=100,
font= ('helvetica',11,'bold'),command=lambda: threading.Thread(target=end_call).start()).pack()
mainloop()
#The lines below are used to test this individual file and
#does not affect calling the functions in the Unlock_Conditions file
#Uncomment the two lines below to test this individual file
#If uncommented, the other two threads (cameras) will not start
#covidConditions = {"questions": False}
#CovidQuestionnaire(covidConditions)
import cv2
from Thermal_Camera import*
from Mask_Detector import*
from Outside_GUI_1106 import*
from threading import Thread
from time import sleep
import RPi.GPIO as GPIO
from tkinter import *
from tkinter import messagebox
import vlc
global nM
nM = vlc.MediaPlayer("/home/charlie/Desktop/Outside_RaspberryPi/no_mask.mp3")
global eT
eT = vlc.MediaPlayer("/home/charlie/Desktop/Outside_RaspberryPi/elev_temp.mp3")
#Raspberry Pi lets you know if the GPIO is already being used. A warning is displayed if it is. We wanted to mute this warning.
GPIO.setwarnings(False)
#BCM defines broadcom. Each GPIO is based on function number.
GPIO.setmode(GPIO.BCM)
#Defining GPIO21 as an output and it starts low.
GPIO.setup(21, GPIO.OUT, initial=GPIO.LOW)
#Defining all covid conditions as started as False
covidConditions = {"thermal": True,"mask": False, "questions":False}
#Targets are the definitions within the corresponding .py files
t1 = Thread(target= maskcamera, args=(covidConditions, ))
t2 = Thread(target= CovidQuestionnaire, args=(covidConditions, ))
t3 = Thread(target= tempcamera, args=(covidConditions, ))
#This starts the threads
t1.start()
t2.start()
t3.start()
def UnlockDoor():
GPIO21 = 21
GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.OUT, initial=GPIO.LOW)
global GPIO21_state
GPIO.output(21, 1)
sleep(5)
#Wait 5 seconds
GPIO.output(21, 0)
#Do not need the below code but keeping it just in case
#global GPIO21_state
#GPIO.output(21, True)
#sleep(5)
#GPIO.output(21, False)
covidConditions["questions"]= False
while True:
if (covidConditions["thermal"] == True and covidConditions["mask"] == True and covidConditions["questions"] == True):
UnlockDoor()
print(covidConditions)
#The following lines of code are for alerting the user of their mask or temperature status.
elif (covidConditions["thermal"] == False):
GPIO.output(21,0)
#eT.play()
messagebox.showwarning("Temperature Check Warning System","The system is detecting your temperature to be elevated. Please click 'Start Call' to speak to the front desk staff.")
sleep(5)
elif (covidConditions["mask"] == False):
GPIO.output(21,0)
#nM.play()
messagebox.showwarning("Mask Check Warning System", "The system has detected that you are not wearing a mask. Please put on a mask.")
sleep(5)
from gpiozero import *
from gpiozero.pins.pigpio import PiGPIOFactory
from tkinter import *
from tkinter import messagebox
from tkinter import font as tkFont
from functools import partial
from time import sleep
from vidstream import AudioSender
from vidstream import AudioReceiver
import threading
#This will work with either eth0 or wlan0
#Works both with ethernet or wifi but we do not want this on WiFi
global fact
#Outside Raspberry Pi eth0 ip
fact = PiGPIOFactory(host='169.254.176.185')
#Since we do not need PWM, calling the LED class is ideal for this instance
global relay
relay = LED(21,pin_factory=fact)
receiver = AudioReceiver('169.254.167.227',5555)
sender = AudioSender('169.254.176.185',9999)
def start_call():
receiver.start_server()
sender.start_stream()
def end_call():
receiver.stop_server()
sender.stop_stream()
#receiver = AudioReceiver('169.254.167.227', 5555) #This will be changed on the other device
#receive_thread = threading.Thread(target = receiver.start_server)
#sender = AudioSender('169.254.176.185', 9999) #This will be changed on the other device
#sender_thread = threading.Thread(target=sender.start_stream)
#receive_thread.start()
#sender_thread.start()
def popup(buttons):
opener = messagebox.askyesno("Door Open Button",
"Are you sure you want to unlock the front door?")
if opener == 1:
#opens the door for 5 seconds
relay.on()
status = messagebox.showwarning("Door Status",
"FRONT DOOR UNLOCKED!")
sleep(5)
relay.off()
#This sleep is needed to end the script if not it gets stuck in a loop
sleep(.1)
else:
#Makes sure that the door stays locked when "no" is selected
relay.off()
closed = messagebox.showwarning("Door Status",
"FRONT DOOR STILL LOCKED.")
def open_button(buttons):
root = Tk()
#Uncomment for uncloasable fullscreen
root.attributes('-fullscreen',True)
label = Label(root, text= "Front Door Remote Access",
font=('helvetica',20,'bold')).pack()
door = Button(root, text= "Open The Door",bg='orange',fg='black',
font=('helvetica',40,'bold'),command=lambda:popup(buttons)).pack(fill=X,ipady=10)
start_button = Button(root,text= "Start Call", fg = "green",
font=('helvetica',40,'bold'), command=lambda: start_call()).pack(fill=X,ipady=10)
end_button = Button(root,text= "End Call", fg = "red",
font=('helvetica',40,'bold'), command=lambda: end_call()).pack(fill=X,ipady=10)
mainloop()
buttons = {"questions": False}
open_button(buttons)
bottom of page