fix: flash ON time = pre_flash_advance + flash_duration

This commit is contained in:
2026-07-21 00:23:45 +02:00
parent bc5f9213ec
commit fc9e9c7def
+49 -7
View File
@@ -190,25 +190,60 @@ class LEDService:
step += 1 step += 1
def _effect_countdown(self, duration: float = 5.0): def _effect_countdown(self, duration: float = 5.0):
cfg = self._cfg.get_effect("countdown")
c = cfg.color
n = self._cfg.count n = self._cfg.count
blank = WS_Color(0, 0, 0) blank = WS_Color(0, 0, 0)
color = WS_Color(c[0], c[1], c[2])
# Mode sombre : rampe progressive avec couleur flash pour stabiliser AWB caméra
lux = self._ambient_lux
dark_mode = self._cfg.auto_brightness and lux >= 0 and lux < 50
if dark_mode:
flash_cfg = self._cfg.get_effect("capture")
fc = flash_cfg.color
color = WS_Color(fc[0], fc[1], fc[2])
# Brightness cible du flash
target_br = 255 if lux < 50 else (int(255 - (lux - 50) / 130 * 135) if lux < 180 else 80)
# Rampe : atteindre target_br quand il reste pre_flash_advance secondes
ramp_duration = max(0.1, duration - self._cfg.pre_flash_advance)
orig_br = self._cfg.brightness
logger.info("Countdown mode sombre: rampe 0→%d sur %.1fs puis stable", target_br, ramp_duration)
if HAS_WS281X and self._strip:
self._strip.setBrightness(0)
self._fill(color)
else:
cfg = self._cfg.get_effect("countdown")
c = cfg.color
color = WS_Color(c[0], c[1], c[2])
self._fill(blank) self._fill(blank)
t_start = time.time() t_start = time.time()
while not self._cmd_event.is_set() and not self._stop_event.is_set(): while not self._cmd_event.is_set() and not self._stop_event.is_set():
elapsed = time.time() - t_start elapsed = time.time() - t_start
ratio = min(elapsed / duration, 1.0) ratio = min(elapsed / duration, 1.0)
if dark_mode:
# Rampe de 0 → target_br jusqu'à ramp_duration, puis stable à target_br
if elapsed < ramp_duration:
br = int(target_br * elapsed / ramp_duration)
else:
br = target_br
if HAS_WS281X and self._strip:
self._strip.setBrightness(br)
self._strip.show()
else:
leds_on = int(ratio * n) leds_on = int(ratio * n)
for i in range(n): for i in range(n):
self._strip.setPixelColor(i, color if i < leds_on else blank) self._strip.setPixelColor(i, color if i < leds_on else blank)
self._strip.show() self._strip.show()
if ratio >= 1.0: if ratio >= 1.0:
break break
time.sleep(0.04) time.sleep(0.04)
# En mode sombre, restaurer brightness normale (capture le fera aussi, mais par sécurité)
if dark_mode and HAS_WS281X and self._strip:
self._strip.setBrightness(orig_br)
def _effect_capture(self): def _effect_capture(self):
"""Flash photo. """Flash photo.
@@ -241,15 +276,22 @@ class LEDService:
if HAS_WS281X and self._strip: if HAS_WS281X and self._strip:
self._strip.setBrightness(flash_brightness) self._strip.setBrightness(flash_brightness)
# Le flash démarre pre_flash_advance secondes AVANT la photo.
# La durée ON doit couvrir ce délai + la durée d'exposition.
# Sinon les LEDs s'éteignent avant que la photo soit prise.
effective_on_time = self._cfg.pre_flash_advance + cfg.flash_duration
try: try:
for _ in range(cfg.flashes): for i in range(cfg.flashes):
if self._cmd_event.is_set(): if self._cmd_event.is_set():
break break
self._fill(flash_color) self._fill(flash_color)
time.sleep(cfg.flash_duration) # Premier flash : durée étendue pour couvrir le délai + expo
# Flashs suivants : durée normale (décoratif post-capture)
on_time = effective_on_time if i == 0 else cfg.flash_duration
time.sleep(on_time)
self._fill(off) self._fill(off)
# Pause inter-flash plus courte que le flash lui-meme if i < cfg.flashes - 1:
if _ < cfg.flashes - 1:
time.sleep(cfg.flash_duration * 0.4) time.sleep(cfg.flash_duration * 0.4)
finally: finally:
# Toujours restaurer la luminosite normale meme en cas d'erreur # Toujours restaurer la luminosite normale meme en cas d'erreur