Files
photoBooth/backend/api/leds_api.py
T
admin 4b188ce819
🚀 Deploy — JH Photomaton / 🔍 Vérification (push) Has been cancelled
🚀 Deploy — JH Photomaton / 🍓 Deploy sur le Pi (push) Has been cancelled
feat: relay inversé, LED idle solid, luminosité manuelle, auto-flash lux
2026-07-17 10:32:43 +02:00

137 lines
4.4 KiB
Python

"""API de contrôle des LEDs WS2812b."""
import logging
from fastapi import APIRouter, Request, Query
from fastapi.responses import JSONResponse
logger = logging.getLogger(__name__)
router = APIRouter()
@router.get("/leds/status")
async def led_status(request: Request):
led = request.app.state.led_service
return {"effect": led.current_effect}
@router.post("/leds/effect")
async def set_effect(
request: Request,
effect: str = Query(..., description="idle | countdown | capture | captured | finished | printing | error | disabled | off"),
):
"""Force un effet LED (admin uniquement, pas de vérification auth ici — à protéger via Zoraxy)."""
valid = ("idle", "countdown", "capture", "captured", "finished", "printing", "error", "disabled", "off")
if effect not in valid:
return JSONResponse({"error": f"Effet invalide. Valeurs: {valid}"}, status_code=400)
led = request.app.state.led_service
ws = request.app.state.ws_manager
led.play(effect)
await ws.broadcast({"type": "led_effect", "effect": effect})
return {"ok": True, "effect": effect}
@router.post("/leds/color")
async def set_color(
request: Request,
r: int = Query(default=0, ge=0, le=255),
g: int = Query(default=0, ge=0, le=255),
b: int = Query(default=0, ge=0, le=255),
):
"""Couleur fixe immédiate sur tout l'anneau."""
led = request.app.state.led_service
led.set_color(r, g, b)
return {"ok": True, "color": [r, g, b]}
@router.post("/leds/off")
async def leds_off(request: Request):
led = request.app.state.led_service
led.play("off")
return {"ok": True}
@router.get("/leds/brightness")
async def get_brightness(request: Request):
cfg = request.app.state.config.leds
return {"brightness": cfg.brightness, "auto_brightness": cfg.auto_brightness}
@router.put("/leds/brightness")
async def set_brightness(
request: Request,
value: int = Query(..., ge=0, le=255),
save: bool = Query(default=True),
):
"""Regle la luminosite globale (0-255) et l'applique immediatement."""
led = request.app.state.led_service
led.set_brightness(value)
if save:
config_svc = request.app.state.config_service
config_svc.save_led_brightness(value)
return {"ok": True, "brightness": value}
@router.put("/leds/auto-brightness")
async def set_auto_brightness(
request: Request,
enabled: bool = Query(...),
save: bool = Query(default=True),
):
"""Active ou desactive la luminosite automatique du flash selon l'ambiance."""
cfg = request.app.state.config.leds
cfg.auto_brightness = enabled
if save:
config_svc = request.app.state.config_service
config_svc.save_led_auto_brightness(enabled)
return {"ok": True, "auto_brightness": enabled}
@router.get("/leds/effects")
async def get_effects(request: Request):
"""Retourne la configuration de tous les effets LED."""
cfg = request.app.state.config.leds
return {
name: {
"color": effect.get("color", [0, 0, 0]),
"flash_duration": effect.get("flash_duration", 0.1),
"flashes": effect.get("flashes", 2),
"speed": effect.get("speed", 0.05),
"duration": effect.get("duration", 2.0),
}
for name, effect in cfg.effects.items()
}
@router.put("/leds/effect/{effect_name}")
async def update_effect(
request: Request,
effect_name: str,
r: int = Query(default=None, ge=0, le=255),
g: int = Query(default=None, ge=0, le=255),
b: int = Query(default=None, ge=0, le=255),
flash_duration: float = Query(default=None, ge=0.05, le=2.0),
flashes: int = Query(default=None, ge=1, le=5),
save: bool = Query(default=True),
):
"""Met a jour la configuration d'un effet LED (couleur, timings).
Exemple : PUT /api/leds/effect/capture?r=255&g=200&b=80&flash_duration=0.3&flashes=2
"""
cfg = request.app.state.config.leds
config_svc = request.app.state.config_service
effect_raw = cfg.effects.setdefault(effect_name, {})
if r is not None and g is not None and b is not None:
effect_raw["color"] = [r, g, b]
if flash_duration is not None:
effect_raw["flash_duration"] = flash_duration
if flashes is not None:
effect_raw["flashes"] = flashes
if save:
config_svc.save_led_effect(effect_name, effect_raw)
return {"ok": True, "effect": effect_name, "config": effect_raw}