feat: pre-flash configurable avant fin countdown
This commit is contained in:
+28
-5
@@ -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:
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user