feat: slider pre-flash advance (0-3s) dans settings UI
This commit is contained in:
@@ -158,6 +158,36 @@ async def measure_ambient_lux(request: Request):
|
|||||||
return JSONResponse({"ok": False, "error": str(e)}, status_code=500)
|
return JSONResponse({"ok": False, "error": str(e)}, status_code=500)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/leds/flash-timing")
|
||||||
|
async def get_flash_timing(request: Request):
|
||||||
|
"""Retourne les paramètres de timing du flash."""
|
||||||
|
cfg = request.app.state.config.leds
|
||||||
|
return {
|
||||||
|
"pre_flash_advance": cfg.pre_flash_advance,
|
||||||
|
"countdown_duration": cfg.countdown_duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/leds/flash-timing")
|
||||||
|
async def set_flash_timing(
|
||||||
|
request: Request,
|
||||||
|
pre_flash_advance: float = Query(..., ge=0.0, le=3.0, description="Secondes avant fin countdown pour démarrer le flash"),
|
||||||
|
save: bool = Query(default=True),
|
||||||
|
):
|
||||||
|
"""Règle combien de secondes avant la fin du countdown le flash démarre (0–3s)."""
|
||||||
|
cfg = request.app.state.config.leds
|
||||||
|
cfg.pre_flash_advance = pre_flash_advance
|
||||||
|
if save:
|
||||||
|
config_svc = request.app.state.config_service
|
||||||
|
with open(config_svc.path, encoding="utf-8") as f:
|
||||||
|
import yaml
|
||||||
|
raw = yaml.safe_load(f) or {}
|
||||||
|
raw.setdefault("leds", {})["pre_flash_advance"] = pre_flash_advance
|
||||||
|
with open(config_svc.path, "w", encoding="utf-8") as f:
|
||||||
|
yaml.dump(raw, f, allow_unicode=True, default_flow_style=False)
|
||||||
|
return {"ok": True, "pre_flash_advance": pre_flash_advance}
|
||||||
|
|
||||||
|
|
||||||
@router.put("/leds/effect/{effect_name}")
|
@router.put("/leds/effect/{effect_name}")
|
||||||
async def update_effect(
|
async def update_effect(
|
||||||
request: Request,
|
request: Request,
|
||||||
|
|||||||
@@ -466,6 +466,19 @@ select.field {
|
|||||||
<button class="btn btn-ghost btn-sm" onclick="setFlashPreset(255,220,120,0.25,2)">Blanc neutre</button>
|
<button class="btn btn-ghost btn-sm" onclick="setFlashPreset(255,220,120,0.25,2)">Blanc neutre</button>
|
||||||
<button class="btn btn-ghost btn-sm" onclick="setFlashPreset(255,180,40,0.35,2)">Ambre</button>
|
<button class="btn btn-ghost btn-sm" onclick="setFlashPreset(255,180,40,0.35,2)">Ambre</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top:1rem; padding-top:.75rem; border-top:1px solid var(--border);">
|
||||||
|
<label style="font-size:.82rem; color:var(--text-muted)">⏱ Déclencher le flash
|
||||||
|
<strong id="pre-flash-val">0.5</strong> s avant la fin du countdown</label>
|
||||||
|
<input type="range" id="pre-flash-advance" min="0" max="3" step="0.1" value="0.5"
|
||||||
|
oninput="document.getElementById('pre-flash-val').textContent=parseFloat(this.value).toFixed(1)"
|
||||||
|
style="width:100%; margin-top:.4rem">
|
||||||
|
<div style="display:flex; justify-content:space-between; font-size:.72rem; color:var(--text-muted)">
|
||||||
|
<span>0 s (au moment de la capture)</span><span>3 s (très en avance)</span>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary btn-sm" style="margin-top:.5rem" onclick="savePreFlash()">💾 Sauvegarder</button>
|
||||||
|
<span id="pre-flash-status" style="font-size:.82rem; color:var(--text-muted); margin-left:.5rem"></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -883,6 +896,25 @@ async function loadFlashConfig() {
|
|||||||
document.getElementById('flash-count').value = cap.flashes;
|
document.getElementById('flash-count').value = cap.flashes;
|
||||||
}
|
}
|
||||||
} catch(e) { console.warn('loadFlashConfig:', e); }
|
} catch(e) { console.warn('loadFlashConfig:', e); }
|
||||||
|
// Charger le timing pre-flash
|
||||||
|
try {
|
||||||
|
const t = await api('GET', '/api/leds/flash-timing');
|
||||||
|
const v = t.pre_flash_advance ?? 0.5;
|
||||||
|
document.getElementById('pre-flash-advance').value = v;
|
||||||
|
document.getElementById('pre-flash-val').textContent = v.toFixed(1);
|
||||||
|
} catch(e) { console.warn('loadFlashTiming:', e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
async function savePreFlash() {
|
||||||
|
const v = parseFloat(document.getElementById('pre-flash-advance').value);
|
||||||
|
const status = document.getElementById('pre-flash-status');
|
||||||
|
try {
|
||||||
|
await api('PUT', `/api/leds/flash-timing?pre_flash_advance=${v}`);
|
||||||
|
status.textContent = `✅ Sauvegardé (${v.toFixed(1)} s)`;
|
||||||
|
setTimeout(() => status.textContent = '', 3000);
|
||||||
|
} catch(e) {
|
||||||
|
status.textContent = '❌ Erreur';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function measureAmbient() {
|
async function measureAmbient() {
|
||||||
|
|||||||
Reference in New Issue
Block a user