added camera preview for fun
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import io
|
||||
import sys
|
||||
|
||||
import bme680
|
||||
@@ -8,7 +9,9 @@ import time
|
||||
import threading
|
||||
import pymysql
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from picamera2 import Picamera2
|
||||
|
||||
from starlette.responses import StreamingResponse
|
||||
|
||||
db_user = 'sensor_user'
|
||||
db_password = 'dein_passwort'
|
||||
@@ -52,6 +55,11 @@ sensor_pin = 22
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
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 ---
|
||||
state = 0
|
||||
motion_detected = False # Shared state
|
||||
@@ -59,6 +67,19 @@ temperature = 0
|
||||
humidity = 0
|
||||
pressure = 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
|
||||
@@ -87,6 +108,30 @@ def proxmity_loop():
|
||||
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
|
||||
# @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.start()
|
||||
|
||||
if use_camera:
|
||||
init_camera()
|
||||
#camera_thread = threading.Thread(target=camera_loop, daemon=True)
|
||||
#camera_thread.start()
|
||||
|
||||
print("Sensor thread started")
|
||||
|
||||
@@ -269,6 +318,28 @@ async def getRegression():
|
||||
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
|
||||
# @description Starts the FastAPI app server using Uvicorn.
|
||||
|
||||
Reference in New Issue
Block a user