feat: pre-flash configurable avant fin countdown
🚀 Deploy — JH Photomaton / 🔍 Vérification (push) Has been cancelled
🚀 Deploy — JH Photomaton / 🍓 Deploy sur le Pi (push) Has been cancelled

This commit is contained in:
2026-07-20 23:29:55 +02:00
parent b2ee41c367
commit 69b9cd0901
3 changed files with 35 additions and 6 deletions
+28 -5
View File
@@ -8,8 +8,6 @@ from fastapi import APIRouter, Request, Query
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
router = APIRouter() router = APIRouter()
DEFAULT_COUNTDOWN = 5.0
@router.get("/webhook/photobooth") @router.get("/webhook/photobooth")
async def photobooth_webhook( async def photobooth_webhook(
@@ -20,19 +18,36 @@ async def photobooth_webhook(
led = request.app.state.led_service led = request.app.state.led_service
btn = request.app.state.button_service btn = request.app.state.button_service
ws = request.app.state.ws_manager ws = request.app.state.ws_manager
cfg = request.app.state.config.leds
logger.info("Webhook photobooth: event=%s type=%s", event_key, mediaitem_type) logger.info("Webhook photobooth: event=%s type=%s", event_key, mediaitem_type)
await ws.broadcast({"type": "photobooth_event", "event": event_key, "media_type": mediaitem_type}) await ws.broadcast({"type": "photobooth_event", "event": event_key, "media_type": mediaitem_type})
match event_key: match event_key:
case "counting": case "counting":
led.play("countdown", countdown_duration=DEFAULT_COUNTDOWN) led.play("countdown", countdown_duration=cfg.countdown_duration)
if request.app.state.config.leds.auto_brightness:
# Annuler le pre-flash précédent si toujours en attente
prev = getattr(request.app.state, "pre_flash_task", None)
if prev and not prev.done():
prev.cancel()
# Déclencher le flash X secondes avant la fin du countdown
delay = max(0.0, cfg.countdown_duration - cfg.pre_flash_advance)
task = asyncio.create_task(_delayed_flash(led, delay))
request.app.state.pre_flash_task = task
logger.info(
"Pre-flash schedulé dans %.2fs (countdown=%.1fs advance=%.1fs)",
delay, cfg.countdown_duration, cfg.pre_flash_advance,
)
if cfg.auto_brightness:
pb = request.app.state.photobooth_service pb = request.app.state.photobooth_service
asyncio.create_task(_analyze_ambient_lux(led, pb)) asyncio.create_task(_analyze_ambient_lux(led, pb))
case "capture": case "capture":
led.play("capture") # Flash déjà lancé par le pre-flash depuis counting ; ne pas redémarrer
logger.debug("Event capture recu (pre-flash déjà actif)")
case "captured": case "captured":
led.play("captured") led.play("captured")
@@ -57,6 +72,14 @@ async def photobooth_webhook(
return {"ok": True, "event": event_key} return {"ok": True, "event": event_key}
async def _delayed_flash(led, delay: float):
"""Attend `delay` secondes puis déclenche l'effet flash."""
if delay > 0:
await asyncio.sleep(delay)
led.play("capture")
logger.info("Pre-flash déclenché (délai=%.2fs)", delay)
async def _delayed_relay_on(btn, delay: float): async def _delayed_relay_on(btn, delay: float):
await asyncio.sleep(delay) await asyncio.sleep(delay)
if btn: if btn:
+4
View File
@@ -64,6 +64,8 @@ class LEDConfig:
dma: int = 10 dma: int = 10
strip_type: str = "WS2812" strip_type: str = "WS2812"
effects: dict = field(default_factory=dict) effects: dict = field(default_factory=dict)
countdown_duration: float = 3.0 # Durée du countdown photobooth-app (secondes)
pre_flash_advance: float = 0.5 # Démarrer le flash X sec avant la fin du countdown
def get_effect(self, name: str) -> LEDEffectConfig: def get_effect(self, name: str) -> LEDEffectConfig:
raw = self.effects.get(name, {}) raw = self.effects.get(name, {})
@@ -151,6 +153,8 @@ class ConfigService:
dma=led_raw.get("dma", 10), dma=led_raw.get("dma", 10),
strip_type=led_raw.get("strip_type", "WS2812"), strip_type=led_raw.get("strip_type", "WS2812"),
effects=led_raw.get("effects", {}), effects=led_raw.get("effects", {}),
countdown_duration=led_raw.get("countdown_duration", 3.0),
pre_flash_advance=led_raw.get("pre_flash_advance", 0.5),
) )
if "print" in raw: if "print" in raw:
+3 -1
View File
@@ -39,6 +39,7 @@ leds:
auto_brightness: true auto_brightness: true
brightness: 20 brightness: 20
count: 35 count: 35
countdown_duration: 3.0 # Durée du countdown photobooth-app (secondes)
dma: 10 dma: 10
effects: effects:
capture: capture:
@@ -46,7 +47,7 @@ leds:
- 255 - 255
- 200 - 200
- 80 - 80
flash_duration: 2.0 flash_duration: 1.0
flashes: 1 flashes: 1
mode: flash mode: flash
captured: captured:
@@ -97,6 +98,7 @@ leds:
speed: 0.05 speed: 0.05
freq_hz: 800000 freq_hz: 800000
pin: 18 pin: 18
pre_flash_advance: 0.5 # Démarrer le flash X secondes avant la fin du countdown
strip_type: WS2812 strip_type: WS2812
photobooth: photobooth:
config_file: /home/pi/photobooth-data/config/config.json config_file: /home/pi/photobooth-data/config/config.json