- Icône discrète coin bas-gauche, visible seulement si photostation installée
- Popup PIN (4 chiffres) avant lancement
- Backend : /api/photostation/disponible + /api/photostation/lancer
- kiosk-session.sh : Chromium attend le flag /tmp/photostation_running avant redémarrage
- Script install-photostation.sh pour déploiement sur la Surface
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Si Chromium ou le backend plantent, ils redémarrent automatiquement.
La session LightDM ne se termine jamais → plus d'écran de login intempestif.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Intégration selphy_print (backend CUPS dyesub Mitsubishi CP-K60DW-S)
- Formats impression : 15x20, 10x15, 10x15 2-strips avec cadre et orientation portrait/paysage
- Cadres d'impression par format (strip/10x15/15x20) : upload, sélection, aperçu live
- Cadres démo générés : pellicule noir/vintage/couleurs + bordures classique/doré/rose gold
- Écran de choix de cadre avant capture (clic direct, aperçu grand format)
- Filtres réduits à 3 (Couleur, N&B, Sépia) et appliqués sur tous les strips
- Port 80 via authbind, route /admin avec redirection auto depuis poste distant
- Autologin LightDM corrigé (pam-autologin-service)
- Bouton évacuer bourrage papier dans admin
- Fix : _gp_lock manquant dans Camera.__init__
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
eosremoterelease='Immediate' envoyait GP_EVENT_FILE_ADDED uniquement
pour la 1ere pose (bug Canon/gphoto2 connu). trigger_capture() genere
l'evenement pour CHAQUE pose. En liveview actif (miroir deja leve),
trigger_capture() ne bouge pas le miroir — uniquement l'obturateur.
Timeout reduit 15s -> 12s, poll 500ms -> 200ms (reaction plus rapide).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Retire eosviewfinder=1 avant/apres chaque prise : relancait le liveview
(4-6s de blocage) → timeout 15s → ch=None → photos=[] → S_ACCUEIL
- Le miroir est deja leve par capture_preview() continu, l'obturateur
seul se declenche via eosremoterelease=Immediate
- Logs detailles : chaque etape imprime son resultat pour debug
- Apres capture echouee : _prev_thumbs.append(None) pour garder index cohérent
- S_PREV 2.5s → 1.5s (plus reactif entre les poses)
- Apres capture : revient en S_PREV 0.6s pour montrer la vignette
- Print "Séquence terminée N/M photos" pour suivi
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- post_capture_grace=10 : ignore les erreurs -52 transitoires juste
apres une prise (Canon EOS a besoin ~1s pour stabiliser le capteur)
- Threshold abandon capture : 3 -> 8 erreurs consecutives
- Threshold reconnexion : 5 -> 10 erreurs consecutives
- Avant chaque prise : eosviewfinder=1 pour garantir miroir leve
- Apres prise : viewfinder relance + sleep 1s + drain 8 evenements
- Sim auto-detect : pas de USB reset (evite boucle -52), verification
fonctionnelle avec un capture_preview() avant de valider la camera
- Sim poll : 15s au lieu de 10s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Supprime sleep(0.3) apres chaque capture_preview() reussi
(limitait le live view a ~3fps, cause principale des saccades)
- Fixe crash silencieux thread camera : _nb_retry non initialise
pour errs 1-4 (NameError) -> restructure en for/else propre
- Pellicule live view : _pfit() au lieu de transform.scale() -> plus de distorsion
- draw_capture() : mode pellicule affiché au lieu de fullscreen black
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Admin onglet Système : bouton Quitter (gris) pour fermer l'appli
- Reconnexion caméra : max 10 tentatives (~30s) puis bascule en mode
simulation ; le loop sim reprend la détection automatique toutes les 10s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- _pfit() : helper scale+crop centré pygame sans déformer
- ImageOps.fit() partout : vignettes, galerie, composite (recadrage centré
au lieu de resize qui écrase)
- eosremoterelease 'Immediate' : déclenche l'obturateur Canon en restant
en LV, évite la levée/baisse de miroir à chaque prise
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- draw_galerie() : rendu pellicule (bande film avec perforations) quand le
mode est actif
- _load_gal() : charge les surfs à la taille des cadres pellicule si actif
- S_PREV : 1.5s → 2.5s pour laisser le DSLR revenir en live view
- _usb_reset_done() : utilise unbind/bind sysfs au lieu de usbreset
(unbind/bind = seule méthode qui libère réellement le claim USB)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- _usb_reset_done() : reset USB via usbreset pour libérer tout claim
obsolète avant d'initialiser libgphoto2 (fix erreur -53)
- Appelé au démarrage et dans _cam_loop() toutes les 10s en simulation
- _cam_loop() : log les erreurs d'auto-detect pour diagnostic
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- draw_compte() pellicule : suppression de l'overlay global qui masquait la
bande film pendant le compte à rebours
- _cam_loop() : ne quitte plus en mode simulation, tente une reconnexion
automatique toutes les 8s si le DSLR est branché après démarrage
- _reconnect_cam() : fonctionne aussi depuis le mode simulation (bouton admin)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Le handler utilisait True comme défaut pour tous les toggles, ce qui faisait
que not f.get("pellicule_mode", True) = False au premier clic (toggle semblait
bloqué). Ajout d'un ensemble _false_defs pour les features à défaut False.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Nouveau toggle "Mode pellicule" dans l'onglet Fonctions de l'admin
- _draw_pellicule() : bande noire cinéma avec perforations haut/bas,
cadres numérotés (01A, 02A...) ; le live view est rendu dans le cadre
courant, les photos prises occupent leur case, les futures sont en gris
- draw_preview() / draw_compte() : utilisent _draw_pellicule() quand activé
- _make_composite() : génère une bande simple (non doublée) en mode pellicule
- Thumbnails chargés à _PELL_FH (748px) pour la qualité native en pellicule
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- _make_composite(): crée une image bande (2 rangées) ou grille 2x2 à partir
des photos prises, sauvée en /tmp/photobooth_composite.jpg
- _upload_booth(): upload le composite unique en mode multi au lieu des photos
individuelles
- _draw_multi_strip(): overlay bas avec les cases numérotées — thumbnails pour
les prises faites, cadre pulsant pour la case courante, placeholder gris pour
les suivantes
- draw_preview() / draw_compte(): utilisent _draw_multi_strip() en mode multi
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ajoute deux routes FastAPI :
- GET /s/{code} → galerie HTML mobile avec auto-refresh 15s
- POST /api/sessions/{code}/upload → stockage photo dans session_{code}/
Corrige layout admin : titre sm au lieu de lg, compteur sans chevauchement.
Wizard step 2 : code affiché en lg (96px) au lieu de xxl (300px).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Avant : frontend poll WS toutes les 100ms -> gphoto2 bloquant -> lag
Apres : thread dedie capture en continu a 30fps, pusher asyncio
diffuse a 20fps a tous les clients, frontend dit juste
preview_start / preview_stop
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Preview gphoto2 echoue -> None direct, pas de webcam ni simulation
- Connexion sans DSLR -> mode erreur, camera non connectee
- Suppression _preview_webcam_fallback et _init_preview_fallback
- WS preview : appel direct camera.preview(), plus de logique speciale
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Endpoint /api/systeme/info : IPs par interface, hostname, uptime,
disque, RAM, temperature CPU, version Python, statut camera
- Onglet Infos dans le backoffice avec affichage visuel (barres, couleurs)
- Bouton Actualiser pour rafraichir les donnees en temps reel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Verification etat camera AVANT le lancement (pas de DSLR = erreur immediate)
- Detection erreur camera PENDANT le compte a rebours (pas de capture aveugle)
- Capture : erreur reseau catchee, retry x3, message explicite si echec
- Limite de photos : message + detail au lieu de retour accueil silencieux
- Strip/collage : verification resultat, message si generation echoue
- traiterCapture : try/catch global, plus de retour accueil silencieux
- Overlay erreur : titre + detail lisible, 4s avant retour accueil
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>