- Preview thread : poll uniquement quand ecran capture actif, keepalive 30s sinon - Sequence boot Canon : power cycle relais si absent USB au demarrage - Veille auto 30min : Canon coupe par relais apres inactivite, reveil au preview_start - Stats diagnostic /api/canon/stats : keepalive, preview, captures, connexions - Escalade reconnexion adoucie : pas d'USB reset les 2 premieres tentatives - Hard reset relais 10s (resistance decharge 990ohm sur dummy battery 8V) - Gestion fin evenement : date_fin + bouton terminer + guard 403 impression - Compteur base sur min(papier, ruban) avec cap evenement optionnel - Pre-eclairage countdown : projecteurs ON 3s avant capture pour mesure expo - Canon _configurer_init() : ISO 800, drivemode Single, viewfinder, EXIF preserve - Admin : detail evenement, compteur consommables, galerie impression Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WyN9xFp84P9VaWT3Qe2DXu
301 lines
14 KiB
Markdown
301 lines
14 KiB
Markdown
# Photobooth
|
|
|
|
## Description
|
|
Photobooth professionnel pour location evenementielle.
|
|
Surface 6 + ecran tactile + DSLR Canon (gphoto2) + imprimante sublimation Mitsubishi.
|
|
|
|
## Architecture
|
|
- **Backend** : Python FastAPI + WebSocket
|
|
- **Frontend** : HTML/CSS/JS vanilla dans Chromium kiosk
|
|
- **Camera** : python-gphoto2 (mode simulation si absent)
|
|
- **Impression** : CUPS (pycups)
|
|
- **Email** : SMTP (smtplib)
|
|
|
|
## Fonctionnalites
|
|
Toutes activables/desactivables dans le menu admin cache (appui long 3s coin bas-droit) :
|
|
- Photo simple, multi-shot (strip/collage), GIF anime
|
|
- Filtres (N&B, sepia, vintage, contraste, lumineux, chaud, froid, flou)
|
|
- Overlays / cadres PNG personnalisables
|
|
- Chroma key (fond vert via OpenCV)
|
|
- Impression sublimation
|
|
- Envoi email
|
|
- QR code galerie
|
|
- Compteur photos
|
|
|
|
## Repo Gitea
|
|
https://git.copydev.fr/jules/photobooth
|
|
|
|
## Statut
|
|
Phase 1-3 terminees (backend complet + frontend complet).
|
|
Phase 4 : scripts production (install.sh, start.sh, systemd).
|
|
|
|
## Notes
|
|
- Projet cree le 2026-03-21
|
|
- Mode simulation camera si gphoto2 non installe (dev sans DSLR)
|
|
- Config persistante dans data/config.json
|
|
|
|
---
|
|
|
|
## Infra & réseau
|
|
|
|
### Surface (booth terrain)
|
|
- IP LAN : 192.168.111.39 (DHCP, sujette à changement)
|
|
- IP VPN : 10.10.0.2
|
|
- Accès SSH : `ssh surface` (alias ~/.ssh/config, clé ed25519)
|
|
- User : `jules`, repo : `~/photobooth`
|
|
- **Pas de clavier physique** — toute intervention SSH uniquement
|
|
- Déploiement : pas de systemd (photobooth.service disabled, plante exec 203). Le run = `scripts/kiosk-session.sh` lancé au login LightDM autologin : boucle relance backend + boucle Chromium kiosk. Pour déployer : `git push` depuis dev, puis `kill <pid backend.main>` + `pkill -f 'chromium '` → relance auto avec git pull.
|
|
- Remote debugging Chromium : port 9222
|
|
- Kernel linux-surface avec iptsd (tactile), scale-factor=3
|
|
- `data/config.json` = état runtime (compteur, imprimante) — ne jamais écraser par commit/push depuis dev
|
|
|
|
### LXC 111 (booth-manager / galerie)
|
|
- IP : 192.168.111.211
|
|
- Accès : `ssh root@192.168.111.10` puis `pct exec 111 -- <cmd>`
|
|
- Code : `/opt/photobooth/backend/booth_admin.py`
|
|
- Service : `systemctl restart photobooth`
|
|
- Héberge : booth.copydev.fr (landing, galerie, admin)
|
|
|
|
### WireGuard tunnel
|
|
- Serveur (LXC 111) : wg0, 10.10.0.1/24, port 51820/UDP, enabled
|
|
- Client (Surface) : 10.10.0.2/24
|
|
- Clé publique serveur : `g3s7Gh1Er+LIEI/W91HAVDNIo+gsk/KiajdtoDUQRVo=`
|
|
- Clé privée client : `uH9lesPtezigCDlB6cSCYy87QFxrtLFWcnwi93/YgXM=`
|
|
- Clé publique client : `p+yIc+slDkKXnogvvuohbWlF8iapbI4LxJPH1RCaUig=`
|
|
- Port forward routeur : UDP 51820 → 192.168.111.211
|
|
|
|
### Proxmox PVE
|
|
- IP : 192.168.111.10, accès `ssh root@192.168.111.10`
|
|
|
|
### NPM (Nginx Proxy Manager)
|
|
- IP : 192.168.111.5, port 81
|
|
- Cert wildcard *.copydev.fr ID #2
|
|
|
|
---
|
|
|
|
## Règles de conduite Claude
|
|
|
|
- **Pas de clavier sur la borne** : ne jamais suggérer Ctrl+R, F5, ou actions clavier. Forcer reload via SSH (port 9222) ou restart lightdm/chromium.
|
|
- **Pas de confirmation sur la Surface** : PC dédié, aucun risque, exécuter directement les commandes SSH.
|
|
- **Pas de SSH sauvage** : ne jamais SSH sur des serveurs non demandés sans instruction explicite.
|
|
|
|
---
|
|
|
|
## Matériel
|
|
|
|
### Imprimante sublimation Mitsubishi
|
|
- Reçue le 2026-05-28
|
|
- Erreur 03/01/01 sur K60 = papier mal chargé (pas fin de rouleau)
|
|
|
|
### Module relais USB HID
|
|
- Commandé le 2026-06-23, livraison estimée ~2026-07-01
|
|
- Pour piloter alim secteur Canon (power-cycle PTP freeze) + éclairage booth
|
|
- Intégration via /dev/hidraw* dans le backend Python
|
|
|
|
---
|
|
|
|
## UX dépannage novices
|
|
Utilisateurs finaux = novices (événementiel). Erreurs imprimante : prévoir guides imagés (popup plein écran, étapes numérotées, icônes grandes, pas de codes techniques). Cas : cassette mal insérée, bourrage, fin consommable, câble USB.
|
|
|
|
---
|
|
|
|
## VPN booth (2026-07-04)
|
|
|
|
Tunnel WG a eu une panne le 04/07. Cause probable : wg-quick@wg0 pas enabled au boot, ou Endpoint IP locale.
|
|
|
|
### Procédure fix (clavier USB temporaire)
|
|
|
|
1. `sudo systemctl status wg-quick@wg0 && sudo wg show && cat /etc/wireguard/wg0.conf`
|
|
2. Vérifier Endpoint = `<IP_PUBLIQUE>:51820` (pas 192.168.111.x). IP publique : `curl -s ifconfig.me`
|
|
3. `sudo systemctl enable wg-quick@wg0 && sudo systemctl restart wg-quick@wg0`
|
|
4. Installer watchdog + reverse SSH — voir PROCEDURE_VPN_FIX.md
|
|
|
|
---
|
|
|
|
## LXC 111 — booth.copydev.fr (état au 2026-07-04)
|
|
|
|
Code sur le serveur : `/opt/photobooth/` (PAS dans le repo git local).
|
|
Backup local des fichiers modifiés : `lxc111_backup/` dans ce dossier projet.
|
|
|
|
### Fichiers modifiés sur LXC 111
|
|
- `backend/main.py` (1126 lignes) — endpoints galerie + réservation
|
|
- `backend/booth_admin.py` (808 lignes) — admin panel API + ZIP streaming
|
|
- `frontend/landing.html` (900 lignes) — page vitrine complète
|
|
- `frontend/admin.html` (930 lignes) — panel admin avec validation résa
|
|
- `frontend/gallery.html` (414 lignes) — galerie publique + modal ZIP progress
|
|
|
|
### Endpoints ajoutés
|
|
- `GET /api/disponibilites` → retourne dates réservées (statut "valide" ou "demande")
|
|
- `POST /api/contact` → crée événement + envoie email admin (pas client). Champs : nom, email, telephone, nom_evenement, type, date, formule, theme, nb_invites, impressions, opt_livraison, message
|
|
- `POST /api/contact/valider/{event_id}` → passe statut "valide" + envoie email confirmation au client avec URL galerie + code accès
|
|
|
|
### Landing page (frontend/landing.html)
|
|
- Vitrine commerciale booth.copydev.fr, couleur indigo #5c6bc0
|
|
- 6 cartes prestations (Canon 18Mpx, Mitsubishi sublimation, galerie live, personnalisation, écran tactile, partage)
|
|
- 3 tarifs : Pack 300 (300€), Pack 600 (450€), Livraison & installation (sur devis)
|
|
- Formulaire réservation → crée événement auto → email admin
|
|
- Calendrier dispo : WE = sam+dim (un bloc), semaine = lun→ven (un bloc), même prix. Dates réservées bloquées.
|
|
- Modal accès galerie (code 4 digits)
|
|
- Lien admin caché (coin bas-droit, opacity:0 → hover 0.3)
|
|
|
|
### Admin panel (frontend/admin.html)
|
|
- Section "Demandes en attente" (orange) avec boutons Valider/Refuser
|
|
- Section "Galeries en ligne" séparée
|
|
- `validerReservation()` → `POST /api/contact/valider/{id}` avec `credentials: 'include'`
|
|
|
|
### ZIP galerie
|
|
- Corrigé crash mémoire (648 Mo in-memory → temp file + streaming 1 Mo chunks)
|
|
- Barre de progression dans modal (ReadableStream, affiche Mo reçus + %)
|
|
- Restreint admin only (pas guest)
|
|
|
|
### SMTP
|
|
- Corrigé pour port 587 : STARTTLS (pas SMTP_SSL qui est pour 465)
|
|
- Config OVH : ssl0.ovh.net port 587
|
|
|
|
### Compteur photos
|
|
- `distribuer_photo()` accepte paramètre `copies` et incrémente par ce nombre (pas toujours +1)
|
|
|
|
---
|
|
|
|
## Historique développement (juin-juillet 2026)
|
|
|
|
### Kiosk & production (3-4 juin)
|
|
- Kiosk boucle infinie : backend + Chromium relancés automatiquement, plus d'écran login
|
|
- Impression Mitsubishi K60 + cadres + interface admin distante
|
|
- Chromium : désactivation Translate (--lang=fr + prefs FR), meta notranslate
|
|
- Verrou instance unique kiosk (anti-clignotement)
|
|
- Intégration station d'impression photo (photostation) — popup accueil
|
|
- USB automount avec udiskie dans kiosk-session
|
|
- Détection USB 2 niveaux /media/<user>/<label> + filtre fstype
|
|
- Cadres : choix avec zoom 2.5x + fond photo simulé
|
|
|
|
### Caméra & preview (5-10 juin)
|
|
- Viewfinder permanent + preview live pendant compte à rebours
|
|
- Fix preview + miroir : thread continu, grace period, lock gphoto2
|
|
- Fix caméra : kill gvfsd-gphoto2, race condition viewfinder, exif_transpose
|
|
- Fix strip K60 coupe auto, diagnostic preview
|
|
- Caméra déconnectée : retour accueil automatique + abort capture
|
|
- Bullet-proof caméra : reconnexion auto + fix crash capture + AF LiveView
|
|
- Capture : viewfinder=0 avant prise (AF phase-détection), timeout 20s, spinner UI
|
|
- surveiller_dslr : reset USB auto après 3 échecs → retiré (contre-productif)
|
|
- Fix preview live : position:absolute sur img
|
|
- Remote debugging Chromium port 9222
|
|
- Kiosk : git pull auto + diagnostic caméra dans admin
|
|
|
|
### Imprimante & impression (4-23 juin)
|
|
- Statut détaillé imprimante + message erreur CUPS traduit
|
|
- Bandeau erreur imprimante tous écrans + reset USB
|
|
- Bouton Couper papier (micro-job blanc déclenche le cutter K60)
|
|
- Cadres : preview coin haut-gauche + compteur bloque impression pas capture
|
|
- Pellicule : marge de coupe plus large + warmup LiveView après capture
|
|
- Fix impression pellicule (portrait vs paysage, taille pleine, rotation)
|
|
- Cadre de visée live correspondant au recadrage final pellicule/collage
|
|
- Calibration impression : offsets coupe (mm) + rotation 180° configurable
|
|
- Fix impression paysage : inverser largeur/hauteur
|
|
|
|
### DSLR robustesse (21-28 juin)
|
|
- Flash Canon configurable dans admin
|
|
- DSLR anti-veille : autopoweroff Canon + udev no-autosuspend
|
|
- Keepalive Canon : get_config() toutes les 10s quand preview KO
|
|
- DSLR auto-recovery : USB reset + cadre overlay non-mirroré
|
|
- USB rebind Canon : unbind/rebind sysfs pour recovery hard PTP freeze
|
|
- Escalade recovery : uhubctl power cycle + backoff 60s après 10 échecs
|
|
- Viewfinder off avant capture pour AF phase-detect
|
|
- Viewfinder warmup en arrière-plan (accélération capture)
|
|
|
|
### Email (22 juin)
|
|
- Email plein écran avec suggestions d'adresses précédentes
|
|
- Fermer formulaire avant envoi + raccourcis domaines FR
|
|
- Email spool : file d'attente quand envoi échoue, retry 60s
|
|
- Spool envoi au démarrage uniquement, message "dans la semaine"
|
|
- Rapport email à contact@copydev.fr après vidage du spool
|
|
|
|
### Événements & galerie (22-23 juin)
|
|
- Galerie booth : QR avec auto-login, event_id aléatoire, flyer imprimable
|
|
- Admin : galerie en ligne dans Destinations + booth envoie toutes les photos
|
|
- Gestion événements + cadres par event + fix cadre paysage + dossier non-imprimées
|
|
- Thème Viking Celte : bois sculpté, bronze, entrelacs
|
|
- Cadre imposé visible en overlay sur live + preview + partage
|
|
- Formats activables par événement + cadre imposé exclut strips
|
|
- Lien galerie événement dans admin
|
|
|
|
### Résilience & réseau (26-27 juin)
|
|
- Écran pause, reconnexion WS auto, watchdog systemd, WiFi monitor
|
|
- Admin WiFi : scan réseaux, connexion, mots de passe mémorisés
|
|
- Kiosk : flag maintenance + anti-doublon backend
|
|
- Watchdog systemd + fix stabilité kiosk/backend
|
|
- QR code par photo : popup QR dynamique + page vue photo sur booth
|
|
- Fix QR code URL (routes publiques /g/)
|
|
- Fix QR après photo : corriger share.js qui écrasait afficherQR()
|
|
- Masquer popup QR à chaque changement d'écran
|
|
- Supprimer le timeout auto-retour du menu admin
|
|
|
|
### Admin galerie & copies (30 juin)
|
|
- Admin galerie + compteur copies + flash capture + erreur imprimante toast
|
|
- Bump cache versions (style v12, camera v17, gallery v4)
|
|
|
|
### Admin backoffice (9 juillet)
|
|
- Rubriques Général / Événement dans admin
|
|
- Vidéos situation (tutoriels visuels)
|
|
- Mode surprise
|
|
- Rembobinage ruban (instruction Mitsubishi)
|
|
|
|
### Suivi consommables (12 juillet)
|
|
- Compteur papier, ruban et photos avec diagnostic ratio
|
|
- Compteur poses perdues + ratio corrigé 0.5 (10 poses par feuille, 20 feuilles par rouleau)
|
|
|
|
### Module relais HID + éclairage auto (1-2 août)
|
|
- Module LCUS 4 canaux (5131:2007) piloté via hidapi/ctypes (`backend/relais.py`)
|
|
- Assignation : R1=Proj gauche (NO), R2=Proj droit (NO), R3=Canon alim (NF), R4=libre
|
|
- udev rule `/etc/udev/rules.d/99-usbrelay.rules` pour accès sans sudo
|
|
- 5 endpoints API relais + admin éclairage avec status relais + boutons ON/OFF
|
|
- Éclairage auto : analyse luminosité visage → allume projecteurs selon 3 seuils configurables
|
|
- Power cycle Canon : relais NF = OFF=alimenté, ON=coupé ; intégré en niveau 10 de l'escalade recovery DSLR
|
|
- Bug fix : byte 4 du status LCUS = bruit (0x4F), seuls bytes 1-3 valides
|
|
|
|
### Vidéos didactiques multi-étapes (1 août)
|
|
- Système complet : situations avec N étapes vidéo, chaque étape boucle jusqu'à validation opérateur
|
|
- 6 situations par défaut (montage, démontage, bourrage, rouleau, wifi, calibration)
|
|
- Wizard overlay plein écran avec bouton "OK c'est bon" + navigation étapes
|
|
- Storage `data/videos/{situation}/etape_XX.mp4`, config.json pour toggles/labels
|
|
- 8 endpoints API vidéos + migration ancien format plat
|
|
|
|
### Panneau diagnostic + auto-recovery + overlays erreur (3 août)
|
|
- Onglet "Diagnostic" dans admin : 4 cartes santé (camera/imprimante/relais/système), actions (reconnecter/réactiver/redémarrer), logs live, USB
|
|
- Endpoints : `/api/systeme/sante`, `/api/systeme/logs`, `/api/systeme/redemarrer-backend`, `/api/imprimante/reactiver`, `/api/systeme/usb`
|
|
- Auto-recovery imprimante : `_surveiller_imprimante` toutes les 30s, cupsenable si disabled
|
|
- Overlay erreur utilisateur avec escalade : auto-fix → patience → opérateur → aide vidéo → redémarrage
|
|
- Wizard vidéo connecté aux erreurs avec auto-détection résolution (poll sante)
|
|
- Situation `camera_hs` ajoutée aux vidéos didactiques par défaut
|
|
|
|
### Fix impression galerie + robustesse (2 août)
|
|
- Bug: `imprimante: null` dans config.json → TypeError: subprocess recevait None en argument
|
|
- Cause: `.get("imprimante", "Mitsubishi")` retourne None si la clé existe avec valeur null
|
|
- Fix: pattern `or "Mitsubishi"` dans 5 endroits (printer.py + main.py)
|
|
- statut-detail endpoint: ajout try/except pour ne plus retourner 500
|
|
- api_imprimer: ajout try/except global pour erreurs inattendues
|
|
- Config Surface corrigée : `imprimante` passé de null à "Mitsubishi"
|
|
|
|
### Canon DSLR restart — problème ouvert (2 août)
|
|
- Canon ne redémarre pas après coupure alim secteur (bouton power doit être pressé)
|
|
- Interrupteur doit être laissé sur ON pour que le power cycle fonctionne
|
|
- Si ça ne suffit pas : bypass physique du bouton power (soudure pont ou optocoupler sur canal 4)
|
|
- Camera fixée au plancher, trappe batterie inaccessible
|
|
|
|
---
|
|
|
|
## Commits non pushés (au 2 août 2026)
|
|
|
|
Incluent relais HID, vidéos didactiques, consommables, admin backoffice.
|
|
Push Gitea bloqué (pas de credentials SSH/HTTPS configurés sur Surface).
|
|
|
|
---
|
|
|
|
## Tâches Trello du projet
|
|
|
|
- [📋 À faire] faire essaie avec mon dslr et imprimante ricoh et installer sur ecran tactile terra
|
|
(card_id: 69c1122fec1b558a76e207b0)
|
|
|
|
Utilise `claude-trello` pour mettre à jour les cartes pendant le travail.
|
|
Labels: green=fait, yellow=en cours, red=bloqué, (aucun)=à faire
|