Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b2d3bb1833 | |||
| fc9e9c7def | |||
| bc5f9213ec |
@@ -190,25 +190,60 @@ class LEDService:
|
||||
step += 1
|
||||
|
||||
def _effect_countdown(self, duration: float = 5.0):
|
||||
cfg = self._cfg.get_effect("countdown")
|
||||
c = cfg.color
|
||||
n = self._cfg.count
|
||||
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()
|
||||
while not self._cmd_event.is_set() and not self._stop_event.is_set():
|
||||
elapsed = time.time() - t_start
|
||||
ratio = min(elapsed / duration, 1.0)
|
||||
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 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)
|
||||
for i in range(n):
|
||||
self._strip.setPixelColor(i, color if i < leds_on else blank)
|
||||
self._strip.show()
|
||||
|
||||
if ratio >= 1.0:
|
||||
break
|
||||
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):
|
||||
"""Flash photo.
|
||||
|
||||
@@ -241,15 +276,22 @@ class LEDService:
|
||||
if HAS_WS281X and self._strip:
|
||||
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:
|
||||
for _ in range(cfg.flashes):
|
||||
for i in range(cfg.flashes):
|
||||
if self._cmd_event.is_set():
|
||||
break
|
||||
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)
|
||||
# Pause inter-flash plus courte que le flash lui-meme
|
||||
if _ < cfg.flashes - 1:
|
||||
if i < cfg.flashes - 1:
|
||||
time.sleep(cfg.flash_duration * 0.4)
|
||||
finally:
|
||||
# Toujours restaurer la luminosite normale meme en cas d'erreur
|
||||
|
||||
@@ -39,7 +39,7 @@ leds:
|
||||
auto_brightness: true
|
||||
brightness: 20
|
||||
count: 35
|
||||
countdown_duration: 3.0 # Durée du countdown photobooth-app (secondes)
|
||||
countdown_duration: 5.0 # Durée du countdown photobooth-app (secondes)
|
||||
dma: 10
|
||||
effects:
|
||||
capture:
|
||||
@@ -98,7 +98,7 @@ leds:
|
||||
speed: 0.05
|
||||
freq_hz: 800000
|
||||
pin: 18
|
||||
pre_flash_advance: 0.5 # Démarrer le flash X secondes avant la fin du countdown
|
||||
pre_flash_advance: 2.5 # Démarrer le flash X secondes avant la fin du countdown
|
||||
strip_type: WS2812
|
||||
photobooth:
|
||||
config_file: /home/pi/photobooth-data/config/config.json
|
||||
|
||||
@@ -852,6 +852,18 @@ async function previewFlash() {
|
||||
}
|
||||
}
|
||||
|
||||
function setFlashPreset(r, g, b, duration, flashes) {
|
||||
document.getElementById('flash-r').value = r;
|
||||
document.getElementById('flash-g').value = g;
|
||||
document.getElementById('flash-b').value = b;
|
||||
document.getElementById('flash-duration').value = duration;
|
||||
document.getElementById('flash-dur-val').textContent = duration.toFixed(2);
|
||||
document.getElementById('flash-count').value = flashes;
|
||||
document.getElementById('flash-preview').style.background = `rgb(${r},${g},${b})`;
|
||||
const hex = '#' + [r,g,b].map(v => v.toString(16).padStart(2,'0')).join('');
|
||||
document.getElementById('flash-colorpicker').value = hex;
|
||||
}
|
||||
|
||||
async function saveFlash() {
|
||||
const r = parseInt(document.getElementById('flash-r').value) || 255;
|
||||
const g = parseInt(document.getElementById('flash-g').value) || 200;
|
||||
|
||||
Reference in New Issue
Block a user