added camera preview for fun
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import io
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import bme680
|
import bme680
|
||||||
@@ -8,7 +9,9 @@ import time
|
|||||||
import threading
|
import threading
|
||||||
import pymysql
|
import pymysql
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from picamera2 import Picamera2
|
||||||
|
|
||||||
|
from starlette.responses import StreamingResponse
|
||||||
|
|
||||||
db_user = 'sensor_user'
|
db_user = 'sensor_user'
|
||||||
db_password = 'dein_passwort'
|
db_password = 'dein_passwort'
|
||||||
@@ -52,6 +55,11 @@ sensor_pin = 22
|
|||||||
GPIO.setmode(GPIO.BCM)
|
GPIO.setmode(GPIO.BCM)
|
||||||
GPIO.setup(sensor_pin, GPIO.IN)
|
GPIO.setup(sensor_pin, GPIO.IN)
|
||||||
|
|
||||||
|
# --- Camera Pins
|
||||||
|
camera_pin = 17
|
||||||
|
GPIO.setmode(GPIO.BCM)
|
||||||
|
GPIO.setup(camera_pin, GPIO.IN)
|
||||||
|
|
||||||
# --- Global shared state variables ---
|
# --- Global shared state variables ---
|
||||||
state = 0
|
state = 0
|
||||||
motion_detected = False # Shared state
|
motion_detected = False # Shared state
|
||||||
@@ -59,6 +67,19 @@ temperature = 0
|
|||||||
humidity = 0
|
humidity = 0
|
||||||
pressure = 0
|
pressure = 0
|
||||||
gas_resistance = 0
|
gas_resistance = 0
|
||||||
|
is_recording = False
|
||||||
|
picam2 = None
|
||||||
|
|
||||||
|
def camera_loop():
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
val = GPIO.input(camera_pin)
|
||||||
|
print(val)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Camera error: {e}")
|
||||||
|
finally:
|
||||||
|
GPIO.cleanup()
|
||||||
|
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
# @function proxmity_loop
|
# @function proxmity_loop
|
||||||
@@ -87,6 +108,30 @@ def proxmity_loop():
|
|||||||
GPIO.cleanup()
|
GPIO.cleanup()
|
||||||
|
|
||||||
|
|
||||||
|
def init_camera():
|
||||||
|
global picam2
|
||||||
|
try:
|
||||||
|
camera = Picamera2()
|
||||||
|
|
||||||
|
# capture_file(..., format="jpeg") kodiert die Frames selbst als JPEG.
|
||||||
|
# Der Kamerastream bleibt deshalb ein normaler RGB-Stream.
|
||||||
|
camera_config = camera.create_preview_configuration(main={"format": "RGB888", "size": (640, 480)})
|
||||||
|
camera.configure(camera_config)
|
||||||
|
|
||||||
|
camera.start()
|
||||||
|
picam2 = camera
|
||||||
|
print("Kamera bereit für das Streaming!")
|
||||||
|
except Exception as e:
|
||||||
|
picam2 = None
|
||||||
|
print(f"Kamera konnte nicht initialisiert werden: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
def capture_jpeg_frame(camera):
|
||||||
|
stream = io.BytesIO()
|
||||||
|
camera.capture_file(stream, format="jpeg")
|
||||||
|
return stream.getvalue()
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
# @function sensor_loop
|
# @function sensor_loop
|
||||||
# @description Reads data from the BME680 sensor (temperature, humidity, pressure, gas resistance)
|
# @description Reads data from the BME680 sensor (temperature, humidity, pressure, gas resistance)
|
||||||
@@ -192,6 +237,10 @@ def startup_event():
|
|||||||
database_thread = threading.Thread(target=database_loop, daemon=True)
|
database_thread = threading.Thread(target=database_loop, daemon=True)
|
||||||
database_thread.start()
|
database_thread.start()
|
||||||
|
|
||||||
|
if use_camera:
|
||||||
|
init_camera()
|
||||||
|
#camera_thread = threading.Thread(target=camera_loop, daemon=True)
|
||||||
|
#camera_thread.start()
|
||||||
|
|
||||||
print("Sensor thread started")
|
print("Sensor thread started")
|
||||||
|
|
||||||
@@ -269,9 +318,31 @@ async def getRegression():
|
|||||||
return lineare_regression(countGuest, temps, [0, 60, 120])
|
return lineare_regression(countGuest, temps, [0, 60, 120])
|
||||||
|
|
||||||
|
|
||||||
|
def gen_frames():
|
||||||
|
global picam2
|
||||||
|
while True:
|
||||||
|
camera = picam2
|
||||||
|
if camera is not None:
|
||||||
|
try:
|
||||||
|
frame_bytes = capture_jpeg_frame(camera)
|
||||||
|
|
||||||
|
# MJPEG-Boundary-Stream zusammensetzen
|
||||||
|
yield (b'--frame\r\n'
|
||||||
|
b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Frame-Grabbing: {e}")
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
time.sleep(0.04) # ~25 FPS
|
||||||
|
|
||||||
|
# Der neue FastAPI-Endpoint für dein Frontend
|
||||||
|
@app.get("/video_feed")
|
||||||
|
async def video_feed():
|
||||||
|
return StreamingResponse(gen_frames(), media_type="multipart/x-mixed-replace; boundary=frame")
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
# @entrypoint
|
# @entrypoint
|
||||||
# @description Starts the FastAPI app server using Uvicorn.
|
# @description Starts the FastAPI app server using Uvicorn.
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user