fix: flash ON time = pre_flash_advance + flash_duration
This commit is contained in:
@@ -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])
|
|
||||||
|
|
||||||
self._fill(blank)
|
# 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)
|
||||||
|
|
||||||
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)
|
||||||
leds_on = int(ratio * n)
|
|
||||||
for i in range(n):
|
if dark_mode:
|
||||||
self._strip.setPixelColor(i, color if i < leds_on else blank)
|
# Rampe de 0 → target_br jusqu'à ramp_duration, puis stable à target_br
|
||||||
self._strip.show()
|
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)
|
||||||
|
for i in range(n):
|
||||||
|
self._strip.setPixelColor(i, color if i < leds_on else blank)
|
||||||
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user