"""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/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}