Skip to content

Commit b1a7566

Browse files
Add files via upload
1 parent ddb83d4 commit b1a7566

File tree

3 files changed

+62
-84
lines changed

3 files changed

+62
-84
lines changed

app.py

Lines changed: 53 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
from flask import Flask, render_template, Response, request, jsonify
1+
from fastapi import FastAPI, WebSocket, Request
2+
from fastapi.responses import HTMLResponse, StreamingResponse
3+
from fastapi.templating import Jinja2Templates
24
import cv2
35
import pytesseract
4-
import time
56
import threading
67
import serial
8+
import asyncio
79

8-
app = Flask(__name__)
10+
app = FastAPI()
11+
templates = Jinja2Templates(directory="templates")
912

1013
# All Cameras
11-
outside_garage_cam = cv2.VideoCapture(0)
12-
inside_garage_cam = cv2.VideoCapture(1)
13-
entrance_cam = cv2.VideoCapture(2)
14-
14+
cameras = [cv2.VideoCapture(i) for i in range(3)]
1515
ser = serial.Serial('/dev/ttyUSB0', 115200) # Arduino's serial port
1616
result_message = ""
1717

@@ -24,8 +24,11 @@
2424
# Pytesseract configuration
2525
pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract' # Path to Tesseract OCR executable
2626

27-
def gen_frames(cam):
27+
def gen_frames(cam_index):
28+
cam = cameras[cam_index]
2829
while True:
30+
if not cam.isOpened():
31+
cam.open(cam_index)
2932
success, frame = cam.read()
3033
if not success:
3134
break
@@ -35,9 +38,9 @@ def gen_frames(cam):
3538
yield (b'--frame\r\n'
3639
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
3740

38-
def garage_control():
41+
async def garage_control():
3942
while True:
40-
ret, frame = outside_garage_cam.read()
43+
ret, frame = cameras[0].read()
4144
if ret:
4245
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
4346
# Perform OCR using Pytesseract
@@ -46,68 +49,59 @@ def garage_control():
4649
# Check if the target plate number is recognized
4750
if "your_target_plate" in text:
4851
ser.write(b'OPEN_GARAGE\n')
49-
print("Opening garage for plate 'your_target_plate'")
50-
time.sleep(1)
51-
52-
def audio_detection():
53-
while True:
54-
if detect_doorbell():
55-
print("ringtone detected!")
56-
# Start camera streaming at home entrance
57-
# Notify and view the camera as needed
58-
time.sleep(1)
52+
print("Garage opens for plate 'your_target_plate'")
53+
await asyncio.sleep(1)
5954

60-
def detect_doorbell():
61-
return False
62-
63-
def read_from_arduino():
55+
async def read_from_arduino():
6456
global result_message
6557
while True:
6658
if ser.in_waiting > 0:
6759
line = ser.readline().decode('utf-8').strip()
6860
if line.startswith("RESULT:"):
6961
result_message = line.split("RESULT:")[1]
62+
await asyncio.sleep(0.1)
63+
64+
@app.get("/", response_class=HTMLResponse)
65+
async def index(request: Request):
66+
return templates.TemplateResponse("index.html", {"request": request})
67+
68+
@app.get("/video_feed/{cam_id}")
69+
async def video_feed(cam_id: int):
70+
if 0 <= cam_id < len(cameras):
71+
return StreamingResponse(gen_frames(cam_id), media_type="multipart/x-mixed-replace; boundary=frame")
72+
return "Invalid Camera ID", 404
7073

71-
@app.route('/video_feed/<int:cam_id>')
72-
def video_feed(cam_id):
73-
if cam_id == 0:
74-
return Response(gen_frames(outside_garage_cam), mimetype='multipart/x-mixed-replace; boundary=frame')
75-
elif cam_id == 1:
76-
return Response(gen_frames(inside_garage_cam), mimetype='multipart/x-mixed-replace; boundary=frame')
77-
elif cam_id == 2:
78-
return Response(gen_frames(entrance_cam), mimetype='multipart/x-mixed-replace; boundary=frame')
79-
else:
80-
return "Invalid Camera ID", 404
81-
82-
@app.route('/open_door', methods=['POST'])
83-
def open_door():
74+
@app.post("/open_door")
75+
async def open_door():
8476
ser.write(b'OPEN_DOOR\n')
85-
return "Door Opened", 200
86-
87-
@app.route('/validate_password', methods=['POST'])
88-
def validate_password():
89-
data = request.json
90-
user = data.get('user')
91-
password = data.get('password')
92-
77+
return {"message": "Door Opened"}
78+
79+
@app.post("/validate_password")
80+
async def validate_password(user: str, password: str):
9381
if user in user_passwords and user_passwords[user] == password:
9482
ser.write(b'VALID_PASSWORD\n')
95-
return "Password Validated", 200
96-
else:
97-
return "Invalid Password", 401
83+
return {"message": "Password Validated"}
84+
return {"message": "Invalid Password"}, 401
9885

99-
@app.route('/result')
100-
def result():
86+
@app.get("/result")
87+
async def result():
10188
global result_message
102-
return jsonify(result=result_message)
89+
return {"result": result_message}
90+
91+
@app.websocket("/ws")
92+
async def websocket_endpoint(websocket: WebSocket):
93+
await websocket.accept()
94+
while True:
95+
data = await websocket.receive_text()
96+
if data == "result":
97+
await websocket.send_text(result_message)
98+
99+
if __name__ == "__main__":
100+
threading.Thread(target=asyncio.run, args=(garage_control(),)).start()
101+
threading.Thread(target=asyncio.run, args=(read_from_arduino(),)).start()
102+
import uvicorn
103+
uvicorn.run(app, host="0.0.0.0", port=8000)
104+
103105

104-
@app.route('/')
105-
def index():
106-
return render_template('index.html')
107106

108-
if __name__ == '__main__':
109-
threading.Thread(target=garage_control).start()
110-
threading.Thread(target=audio_detection).start()
111-
threading.Thread(target=read_from_arduino).start()
112-
app.run(host='0.0.0.0', port=5000, debug=True)
113107

ra.jpg

94.8 KB
Loading

templates/index.html

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -125,65 +125,49 @@
125125
<header class="header">
126126
<h1>H3RU Home Control System</h1>
127127
</header>
128-
129128
<div class="content">
130-
<!-- Camera Feed Left -->
131129
<div class="camera-feed">
132130
<h3>Outside Garage Camera</h3>
133131
<div class="camera-box">
134132
<img src="{{ url_for('video_feed', cam_id=0) }}" alt="Outside Garage Camera">
135133
</div>
136134
</div>
137-
138-
<!-- Logo in the Center -->
139135
<div class="logo-container">
140-
<img src="file:///C:/Users/emohi/Desktop/ra.jpg" alt="H3RU Logo">
136+
<img src="file:///C:/Users/emohi/Desktop/H3RU-Home_Control_System-main/ra.jpg" alt="H3RU Logo">
141137
<p>To everyone who can't finish what they started<br>- H3RU</p>
142138
</div>
143-
144-
<!-- Camera Feed Right -->
145139
<div class="camera-feed">
146140
<h3>Inside Garage Camera</h3>
147141
<div class="camera-box">
148142
<img src="{{ url_for('video_feed', cam_id=1) }}" alt="Inside Garage Camera">
149143
</div>
150144
</div>
151145
</div>
152-
153-
<!-- Button Below the Logo -->
154146
<div class="centered-button">
155147
<button id="open-door">Open Door</button>
156148
</div>
157-
158-
<!-- Third Camera Feed Below the Button -->
159149
<div class="camera-feed">
160150
<h3>Entrance Camera</h3>
161151
<div class="camera-box">
162152
<img src="{{ url_for('video_feed', cam_id=2) }}" alt="Entrance Camera">
163153
</div>
164154
</div>
165-
166155
<div id="result-message"></div>
167-
168156
<script>
157+
const ws = new WebSocket("ws://localhost:8000/ws");
169158
document.getElementById('open-door').addEventListener('click', function () {
170159
fetch('/open_door', { method: 'POST' })
171-
.then(response => response.text())
172-
.then(data => {
173-
document.getElementById('result-message').innerText = data;
174-
});
175-
});
176-
177-
function fetchResult() {
178-
fetch('/result')
179160
.then(response => response.json())
180161
.then(data => {
181-
document.getElementById('result-message').innerText = data.result;
162+
document.getElementById('result-message').innerText = data.message;
182163
});
183-
}
184-
185-
setInterval(fetchResult, 1000); // Check results every second
164+
});
165+
ws.onmessage = function (event) {
166+
document.getElementById('result-message').innerText = event.data;
167+
};
168+
setInterval(() => ws.send("result"), 1000);
186169
</script>
187170
</body>
188171

189172
</html>
173+

0 commit comments

Comments
 (0)