first commit
🚀 Deploy — JH Photomaton / 🔍 Vérification (push) Has been cancelled
🚀 Deploy — JH Photomaton / 🍓 Deploy sur le Pi (push) Has been cancelled

This commit is contained in:
2026-07-16 00:55:29 +02:00
commit 209f81aa3d
100 changed files with 17682 additions and 0 deletions
+87
View File
@@ -0,0 +1,87 @@
# Analyse de la configuration photobooth-app
## Problemes identifies et corrections
### CRITIQUES (causent crashs / OOM)
| # | Probleme | Impact | Correction |
|---|----------|--------|------------|
| 1 | `logging_level: "DEBUG"` | CPU+RAM en continu, fichiers logs enormes | -> `WARNING` |
| 2 | `remove_background` actif sur 5/9 actions | MODNet charge ~300-400Mo RAM par traitement | Garder uniquement sur les actions qui changent le fond |
| 3 | `full_still_length: 4608` (14 Mpx) | Image de ~40Mo en RAM par capture | -> `2304` (suffisant pour Selphy 300dpi) |
| 4 | `CAPTURE_CAM_RESOLUTION: 4608x3072` | Le capteur charge l'image pleine res | -> `2304x1536` |
| 5 | `PREVIEW_CAM_RESOLUTION: 2304x1536` | Preview inutilement grande | -> `1152x768` |
| 6 | `original_still_quality: 100` | JPEG non compresse = fichiers 2x plus gros | -> `90` (visuellement identique) |
### Estimation gain RAM avec corrections
```
AVANT (config actuelle):
photobooth-app base ~300 Mo
MODNet charge en RAM ~300 Mo
Image 4608x3072 RGBA ~56 Mo/image
Preview 2304x1536 ~14 Mo
Node-RED (Node.js) ~200 Mo
Chromium ~300 Mo
TOTAL ~1170 Mo (sur 2048 Mo dispo)
-> Marge: ~878 Mo (insuffisant avec traitement)
APRES (config optimisee):
photobooth-app base ~300 Mo
MODNet (si active) ~300 Mo
Image 2304x1536 RGBA ~14 Mo/image (-75%)
Preview 1152x768 ~3 Mo (-78%)
Node-RED DESACTIVE 0 Mo (-200 Mo)
Chromium (optimise) ~200 Mo (-100 Mo)
TOTAL ~817 Mo
-> Marge: ~1231 Mo (suffisant meme avec remove_background)
```
### SECURITE
| # | Probleme | Correction |
|---|----------|------------|
| 7 | `secret_key: "ThisIsTheDefaultSecret"` | Generer une vraie cle: `python3 -c "import secrets; print(secrets.token_hex(32))"` |
| 8 | `admin_password` en clair dans la config | Normal pour photobooth-app, mais ne pas exposer le fichier |
### IMPRESSION
| # | Probleme | Correction |
|---|----------|------------|
| 9 | "Demande d'impression" passe par Node-RED (curl 127.0.0.1:1880) | Remplacer par appel `lp` direct |
| 10 | Script print.sh reference `/home/pi/` | Verifier que le chemin est correct |
| 11 | Actions "Pouet" et "Mailing" inutiles | Supprimees |
### INTERFACE
| # | Probleme | Correction |
|---|----------|------------|
| 12 | Toutes les actions ont `show_button: false` | Au moins 1 action visible (HnB-normal) |
| 13 | `gpio_enabled: false` | -> `true` pour utiliser le GPIO natif |
| 14 | `GALLERY_EMPTY_MSG` en anglais | Traduit en francais |
| 15 | `thumbnail_still_length: 960` | -> `480` (suffisant pour la galerie web) |
### ACTIONS SIMPLIFIEES
**Supprimees** (doublons):
- `background stars` : doublon de `Hnb - Etoile`
- `Hnb - Etoile - copy` : copie de `Hnb - Etoile` avec cadre different
**Actions share supprimees**:
- `Pouet` : action test (echo OK)
- `Mailing action` : email demo (me@mgineer85.de)
- `Printing copies` : doublon de "Impression"
### RESTE A FAIRE
- [ ] Recevoir et analyser `/home/pi/photobooth-data/script/script_print.sh`
- [ ] Remplacer l'appel Node-RED par un appel `lp` direct dans l'action "Demande d'impression"
- [ ] Tester la config optimisee sur le Pi
- [ ] Verifier que le QR share fonctionne avec l'URL `photomaton.lessapinsduweb.com`
- [ ] Generer une vraie `secret_key`
## Fichiers de reference
- Config originale: `config/photobooth-config-backup.json`
- Config optimisee: `config/photobooth-config-optimized.json`
- La config optimisee contient des commentaires `_OPTI_*` pour chaque changement
+222
View File
@@ -0,0 +1,222 @@
# Photomaton - Architecture du projet
Association: Les Sapins Du Web (LSDW)
Events: Hop'N Bloc, anniversaires, etc.
## Hardware
| Composant | Modele | Notes |
|-----------|--------|-------|
| SBC | Raspberry Pi 4 (2 Go RAM) | Contrainte memoire forte |
| Camera | Camera Module 3 officielle | Backend picamera2, ratio 3:2 natif |
| Ecran | HDMI (moniteur/TV) | Interface photobooth-app + Chromium kiosk |
| Bouton | Bouton lumineux 12V + relay | GPIO23 (input) + GPIO12 (relay ON/OFF) |
| LED Strip | NeoPixels 35 LEDs | GPIO18, feedback visuel pendant capture |
| Imprimante 1 | Canon Selphy CP1300 (blanche) | USB, CUPS: Canon_SELPHY_CP1300_usb_blanche |
| Imprimante 2 | Canon Selphy CP1300 (noire) | USB, CUPS: Canon_SELPHY_CP1300_usb_noire |
| WiFi | RaspAP (hotspot dedie) | Pour distribution photos via QR code |
## Software Stack
```
+----------------------------------------------------------+
| Navigateur Web |
| (Chromium kiosk mode, ecran HDMI) |
+----------------------------------------------------------+
| |
| photobooth-app (:8083) Node-RED (:1880) |
| - Capture camera - Bouton GPIO23 (multi-clic) |
| - Post-traitement - Relay bouton GPIO12 |
| - Galerie + QR share - NeoPixels GPIO18 |
| - Interface utilisateur - Dashboard admin impression |
| - File attente SQLite |
| - Gestion CUPS (enable/ |
| disable, cancel jobs) |
+----------------------------------------------------------+
| Zoraxy (reverse proxy + TLS :443) |
+----------------------------------------------------------+
| CUPS + Gutenprint | RaspAP (hotspot WiFi) |
| (impression Selphy x2) | (reseau dedie QR code) |
+----------------------------------------------------------+
| Raspberry Pi OS (Trixie) |
+----------------------------------------------------------+
```
## Flux utilisateur (prise de photo)
```
Bouton physique (GPIO23)
|
v
Node-RED (button-events: clic/double/triple/quadruple)
|
+--> Desactive relay bouton (GPIO12 = OFF)
+--> NeoPixels: vert (countdown)
+--> Appel API photobooth-app: GET /api/actions/image/{N}
|
v
photobooth-app
1. Countdown (5s) affiche sur ecran
2. NeoPixels: blanc (flash) <-- via webhook -> Node-RED
3. Capture Camera Module 3 (picamera2)
4. NeoPixels: violet (captured)
5. Post-traitement (cadre, remove_background si active)
6. Photo ajoutee a la galerie
7. NeoPixels: bleu (finished) puis vert apres 2s
8. Reactive relay bouton (GPIO12 = ON)
9. QR code affiche pour telecharger via WiFi
```
## Flux impression
```
Utilisateur: clic "Demander l'impression" dans galerie photobooth-app
|
v
photobooth-app: share_command = curl Node-RED /api/photobooth-custom/ask_print
|
v
Node-RED:
1. Recupere l'UID de la photo via API photobooth /api/mediacollection
2. Insere dans SQLite (photo-to-print.sqlite)
3. Affiche dans le dashboard admin (/dashboard)
|
v
Admin (sur telephone via WiFi):
- Voit la demande dans le tableau avec preview
- Clic "OK" = lance impression via script_print.sh (crop 3:2 + lp)
- Clic "x" = annule la demande
- Peut aussi cancel/clear les jobs CUPS, enable/disable imprimantes
```
## GPIO
| GPIO | Pin physique | Fonction | Controle par |
|------|-------------|----------|--------------|
| 12 | 32 | Relay bouton 12V (output) | Node-RED |
| 17 | 11 | Shutdown (hold 2s) | photobooth-app |
| 18 | 12 | NeoPixels 35 LEDs (output) | Node-RED (rpi-neopixels) |
| 20 | 38 | Job abort | photobooth-app |
| 22 | 15 | Job reject / Collage GPIO | photobooth-app |
| 23 | 16 | Bouton physique (input, pull-up) | Node-RED (button-events) |
| 27 | 13 | Job next | photobooth-app |
## Modes photo (bouton multi-clic)
| Clics | Mode | Action photobooth-app | remove_background |
|-------|------|----------------------|-------------------|
| 1 | HnB normal | /api/actions/image/0 | Non |
| 2 | HnB etoile | /api/actions/image/1 | Oui |
| 3 | HnB cailloux | /api/actions/image/2 | Oui |
| 4 | HnB light | /api/actions/image/3 | Oui |
| Long press | Demande impression | /api/share/actions/latest/0 | - |
## Ports reseau
| Service | Port | Process | Notes |
|---------|------|---------|-------|
| SSH | 22 | sshd | Acces distant |
| DNS | 53 | dnsmasq | RaspAP, resolution domaines locaux |
| HTTP | 80 | zoraxy | Redirect -> HTTPS |
| HTTPS | 443 | zoraxy | Reverse proxy principal |
| CUPS | 631 | cupsd | Administration imprimantes |
| Node-RED | 1880 | node-red | Dashboard admin + GPIO + NeoPixels |
| Zoraxy admin | 5487 | zoraxy | Panel admin (localhost only) |
| Zoraxy admin | 8001 | zoraxy | Panel admin (expose via sous-domaine) |
| RaspAP API | 8081 | uvicorn/python3 | API backend RaspAP (/etc/raspap/api/) |
| RaspAP | 8082 | lighttpd | Interface admin WiFi |
| photobooth-app | 8083 | python | Interface web principale |
| ~~rpcbind~~ | ~~111~~ | ~~rpcbind~~ | **INUTILE - a desactiver** |
## Domaines (Zoraxy reverse proxy)
| Sous-domaine | Upstream | Service |
|-------------|----------|---------|
| `photomaton.lessapinsduweb.com` | 127.0.0.1:8083 | photobooth-app (WebSocket ON) |
| `photomaton-nodered.lessapinsduweb.com` | 127.0.0.1:1880 | Node-RED dashboard |
| `photomaton-raspap.lessapinsduweb.com` | 127.0.0.1:8082 | RaspAP admin |
| `photomaton-zoraxy.lessapinsduweb.com` | 127.0.0.1:8001 | Zoraxy admin |
- Certificats TLS geres par Zoraxy
- QR share: `https://photomaton.lessapinsduweb.com/sharepage/#?url=...`
- Chaque service gere sa propre authentification
## Reseau WiFi (RaspAP)
| Element | Valeur |
|---------|--------|
| Interface | wlan0 |
| IP du Pi | 10.3.141.1 |
| Plage DHCP | 10.3.141.50 - 10.3.141.254 (~200 clients) |
| Masque | 255.255.255.0 |
| Bail DHCP | 12h |
| DNS | dnsmasq sur le Pi (port 53) |
| Internet | AUCUN (captive portal) |
### Resolution DNS (dnsmasq)
```
# /etc/dnsmasq.d/090_custom_local_hotspot.conf
address=/lessapinsduweb.com/10.3.141.1 # *.lessapinsduweb.com -> Pi
address=/photomaton.lessapinsduweb.com/10.3.141.1 # explicite
address=/#/127.0.0.1 # tout le reste -> null (pas d'internet)
```
Flux QR code :
1. Telephone se connecte au WiFi "Photomaton"
2. Recoit IP en 10.3.141.x via DHCP, DNS = 10.3.141.1
3. Scan QR code -> `https://photomaton.lessapinsduweb.com/sharepage/...`
4. dnsmasq resout vers 10.3.141.1 (le Pi)
5. Zoraxy (:443) sert la page via HTTPS
6. photobooth-app (:8083) fournit la photo
## Fichiers sur le Pi
```
/home/pi/
photobooth-data/
media/
processed_full/ # Photos traitees (pleine resolution)
script/
script_print.sh # Script d'impression avec load-balancing
log/ # Logs quotidiens
photo-to-print.sqlite # File d'attente d'impression (Node-RED)
userdata/
hopnbloc/
frames/ # Cadres PNG 2000x1333 (ratio 3:2)
backgrounds/ # Fonds pour remove_background
LSDW/
lulu-versaire2.png # Cadre anniversaire
logo/logo.jpeg # Logo LSDW
demoassets/
backgrounds/ # Fonds demo (etoiles, etc.)
frames/ # Cadres demo
```
## Fichiers du projet (ce repo)
```
photomaton/
scripts/
optimize-system.sh # Optimisation OS pour 2Go RAM
setup-printer.sh # Configuration CUPS + Selphy CP1300
setup-photobooth.sh # Installation complete
script_print.sh # Script d'impression optimise
health-check.sh # Surveillance sante du systeme
maintenance.sh # Nettoyage automatique quotidien
config/
photobooth-config-backup.json # Config originale (sauvegarde)
photobooth-config-optimized.json # Config optimisee
gpio-notes.conf # Documentation GPIO
zoraxy-notes.conf # Notes Zoraxy
nodered-flows-backup.json # Backup flows Node-RED
systemd/
photobooth-app.service # Service robuste avec auto-restart
photobooth-watchdog.service # Health check
photobooth-watchdog.timer # Toutes les 2 minutes
photobooth-maintenance.service # Nettoyage
photobooth-maintenance.timer # Quotidien a 4h
docs/
ARCHITECTURE.md # Ce fichier
ANALYSE-CONFIG.md # Analyse detaillee des problemes
```
+777
View File
@@ -0,0 +1,777 @@
# Photomaton LSDW - Guide complet
> Projet photomaton de l'association **Les Sapins Du Web** (LSDW)
> Events : Hop'N Bloc, anniversaires, etc.
> Derniere mise a jour : Juin 2026
---
## Table des matieres
1. [Hardware](#1-hardware)
2. [Software Stack](#2-software-stack)
3. [Architecture reseau](#3-architecture-reseau)
4. [Flux utilisateur](#4-flux-utilisateur)
5. [GPIO et bouton physique](#5-gpio-et-bouton-physique)
6. [Configuration photobooth-app](#6-configuration-photobooth-app)
7. [Impression (Canon Selphy CP1300)](#7-impression-canon-selphy-cp1300)
8. [Node-RED](#8-node-red)
9. [Analyse des problemes et optimisations](#9-analyse-des-problemes-et-optimisations)
10. [Guide de deploiement](#10-guide-de-deploiement)
11. [Fichiers du projet](#11-fichiers-du-projet)
12. [Maintenance et surveillance](#12-maintenance-et-surveillance)
13. [Questions en suspens](#13-questions-en-suspens)
---
## 1. Hardware
| Composant | Modele | Notes |
|-----------|--------|-------|
| SBC | Raspberry Pi 4 (**2 Go RAM**) | Contrainte memoire forte |
| OS | Raspberry Pi OS / Debian 13 Trixie | Reference 2025-12-04, pi-gen stage4 |
| Camera | Camera Module 3 officielle | Backend picamera2, ratio 3:2 natif (4608x3072) |
| Ecran | Moniteur/TV HDMI | Chromium kiosk mode (Wayland/labwc) |
| Bouton | Bouton lumineux 12V + relay | GPIO23 (input) + GPIO12 (relay ON/OFF) |
| LED Strip | NeoPixels WS2812 (35 LEDs) | GPIO18, feedback visuel pendant capture |
| Imprimante 1 | Canon Selphy CP1300 (blanche) | USB, CUPS: `Canon_SELPHY_CP1300_usb_blanche` |
| Imprimante 2 | Canon Selphy CP1300 (noire) | USB, CUPS: `Canon_SELPHY_CP1300_usb_noire` |
| WiFi | Chip WiFi interne RPi4 | Hotspot via RaspAP |
### Format d'impression
- Papier : **100 x 150 mm** (carte postale, 4x6 pouces)
- Ratio : **3:2** (identique au capteur Camera Module 3)
- Resolution minimum a 300 dpi : 1770 x 1182 px
- Cadres PNG : **2000 x 1333 px** (ratio 3:2)
---
## 2. Software Stack
### Schema general
```
+----------------------------------------------------------+
| Navigateur Web |
| Chromium kiosk (Wayland, labwc) |
| ~/Desktop/photobooth-app.desktop |
+----------------------------------------------------------+
| |
| photobooth-app (:8083) Node-RED (:1880) |
| via pipx venv via npm |
| - Capture camera - Bouton GPIO23 (multi-clic) |
| - Post-traitement - Relay bouton GPIO12 |
| - Galerie + QR share - NeoPixels GPIO18 |
| - Interface utilisateur - Dashboard admin impression |
| - File attente SQLite |
| - Gestion CUPS |
| |
+----------------------------------------------------------+
| Zoraxy (reverse proxy + TLS :443) |
| ~/zoraxy/ |
+----------------------------------------------------------+
| CUPS + Gutenprint | RaspAP (hotspot WiFi) |
| Canon Selphy CP1300 x2 | lighttpd :8082 |
+----------------------------------------------------------+
| uvicorn :8081 (API backend RaspAP) |
+----------------------------------------------------------+
| Raspberry Pi OS / Debian 13 Trixie |
+----------------------------------------------------------+
```
### Versions et chemins
| Composant | Chemin / Info |
|-----------|--------------|
| photobooth-app | `~/.local/share/pipx/venvs/photobooth-app/` |
| Donnees photobooth | `~/photobooth-data/` |
| Node-RED | `~/.node-red/` |
| Zoraxy | `~/zoraxy/` |
| Config Zoraxy | `~/zoraxy/conf/proxy/` |
| RaspAP API | `/etc/raspap/api/` (uvicorn :8081) |
| Chromium | `/usr/bin/chromium` (pas chromium-browser, Trixie) |
| Kiosk desktop | `~/Desktop/photobooth-app.desktop` |
---
## 3. Architecture reseau
### Ports en ecoute
| Service | Port | Process | Role |
|---------|------|---------|------|
| SSH | 22 | sshd | Acces distant |
| DNS | 53 | dnsmasq | RaspAP, resolution domaines locaux |
| HTTP | 80 | zoraxy | Redirect -> HTTPS |
| HTTPS | 443 | zoraxy | Reverse proxy principal |
| CUPS | 631 | cupsd | Administration imprimantes |
| Node-RED | 1880 | node-red | Dashboard admin + GPIO + NeoPixels |
| Zoraxy admin | 5487 | zoraxy | Panel admin (localhost only) |
| Zoraxy admin | 8001 | zoraxy | Panel admin (expose via sous-domaine) |
| RaspAP API | 8081 | uvicorn/python3 | API backend RaspAP (/etc/raspap/api/) |
| RaspAP | 8082 | lighttpd + php-fpm | Interface admin WiFi |
| photobooth-app | 8083 | python (pipx) | Interface web principale |
| ~~rpcbind~~ | ~~111~~ | ~~rpcbind~~ | **INUTILE - a desactiver** |
### Reverse proxy Zoraxy
Zoraxy ecoute sur les ports 80 (HTTP redirect) et 443 (HTTPS) et route vers les services locaux :
| Sous-domaine | Upstream | Service | Notes |
|-------------|----------|---------|-------|
| `photomaton.lessapinsduweb.com` | 127.0.0.1:8083 | photobooth-app | WebSocket ON, ChunkedTransfer OFF |
| `photomaton-nodered.lessapinsduweb.com` | 127.0.0.1:1880 | Node-RED | Dashboard impression |
| `photomaton-raspap.lessapinsduweb.com` | 127.0.0.1:8082 | RaspAP | Config WiFi |
| `photomaton-zoraxy.lessapinsduweb.com` | 127.0.0.1:8001 | Zoraxy admin | Self-management |
- Certificats TLS geres par Zoraxy
- Chaque service gere sa propre authentification
- `DisableChunkedTransferEncoding: true` sur le proxy photobooth (necessaire pour le livestream)
### WiFi (RaspAP)
| Element | Valeur |
|---------|--------|
| Interface | wlan0 |
| IP du Pi | 10.3.141.1 |
| Plage DHCP | 10.3.141.50 - 10.3.141.254 (~200 clients) |
| Masque | 255.255.255.0 |
| Bail DHCP | 12h |
| DNS | dnsmasq sur le Pi (port 53) |
| Internet | **AUCUN** (captive portal) |
### Resolution DNS (dnsmasq)
```
# /etc/dnsmasq.d/090_custom_local_hotspot.conf
address=/lessapinsduweb.com/10.3.141.1 # *.lessapinsduweb.com -> Pi
address=/photomaton.lessapinsduweb.com/10.3.141.1 # explicite
address=/#/127.0.0.1 # tout le reste -> null (pas d'internet)
```
Les telephones connectes au WiFi ne peuvent acceder qu'aux sous-domaines `*.lessapinsduweb.com`. Tout le reste est bloque (pas d'internet).
---
## 4. Flux utilisateur
### Prise de photo
```
Bouton physique (GPIO23)
|
v
Node-RED (button-events: clic/double/triple/quadruple)
|
+--> Desactive relay bouton (GPIO12 = OFF)
+--> NeoPixels: vert (countdown)
+--> Appel API photobooth-app: GET /api/actions/image/{N}
|
v
photobooth-app
1. Countdown (5s) affiche sur ecran
2. NeoPixels: blanc (flash) <-- webhook -> Node-RED
3. Capture Camera Module 3 (picamera2)
4. NeoPixels: violet (captured)
5. Post-traitement (cadre, remove_background si active)
6. Photo ajoutee a la galerie
7. NeoPixels: bleu (finished) puis vert apres 2s
8. Reactive relay bouton (GPIO12 = ON)
9. QR code affiche pour telecharger via WiFi
```
### Recuperation de la photo (QR code)
```
1. Telephone se connecte au WiFi "Photomaton"
2. Recoit IP en 10.3.141.x via DHCP, DNS = 10.3.141.1
3. Scan QR code -> https://photomaton.lessapinsduweb.com/sharepage/#?url=...
4. dnsmasq resout vers 10.3.141.1 (le Pi)
5. Zoraxy (:443) sert la page via HTTPS
6. photobooth-app (:8083) fournit la photo
```
### Impression
```
Utilisateur: clic "Demander l'impression" dans galerie photobooth-app
|
v
photobooth-app: share_command = curl Node-RED /api/photobooth-custom/ask_print
|
v
Node-RED:
1. Recupere l'UID de la photo via API photobooth /api/mediacollection
2. Insere dans SQLite (photo-to-print.sqlite)
3. Affiche dans le dashboard admin (/dashboard)
|
v
Admin (sur telephone via WiFi, https://photomaton-nodered.lessapinsduweb.com/dashboard):
- Voit la demande dans le tableau avec preview photo
- Clic "OK" = lance impression via script_print.sh
- Clic "x" = annule la demande
- Peut aussi cancel/clear les jobs CUPS, enable/disable imprimantes
|
v
script_print.sh:
1. Verifie le ratio de l'image (crop 3:2 si necessaire)
2. Choisit l'imprimante idle (blanche ou noire, load-balancing)
3. Envoie le job via lp -d PRINTER -o landscape -o fit-to-page
```
---
## 5. GPIO et bouton physique
### Mapping GPIO
| GPIO | Pin physique | Fonction | Direction | Controle par |
|------|-------------|----------|-----------|--------------|
| 12 | 32 | Relay bouton lumineux 12V | Output | Node-RED |
| 17 | 11 | Shutdown (maintien 2s) | Input | photobooth-app |
| 18 | 12 | NeoPixels 35 LEDs WS2812 | Output | Node-RED (neopix.py, sudo) |
| 20 | 38 | Job abort | Input | photobooth-app |
| 22 | 15 | Job reject / Collage trigger | Input | photobooth-app |
| 23 | 16 | Bouton physique principal | Input (pull-up) | Node-RED (button-events) |
| 27 | 13 | Job next | Input | photobooth-app |
### Modes photo (bouton multi-clic sur GPIO23)
| Clics | Mode | Action API | remove_background |
|-------|------|-----------|-------------------|
| 1 clic | HnB normal | `/api/actions/image/0` | Non |
| 2 clics | HnB etoile | `/api/actions/image/1` | Oui |
| 3 clics | HnB cailloux | `/api/actions/image/2` | Oui |
| 4 clics | HnB light | `/api/actions/image/3` | Oui |
| Appui long | Demande impression | `/api/share/actions/latest/0` | - |
Le multi-clic est gere par le node `button-events` de Node-RED avec :
- Intervalle clic : 500 ms
- Intervalle appui long : 2000 ms
- Debounce : 15 ms
### NeoPixels - Couleurs par evenement
| Evenement | Couleur | Brightness |
|-----------|---------|------------|
| Countdown (counting) | Vert `#008000` | 100 |
| Flash (capture) | Blanc `#FFFFFF` | 255 |
| Captured | Violet `#8A2BE2` | 100 |
| Finished | Bleu `#0000FF` | 100 |
| Idle (apres 2s) | Vert `#008000` | 100 |
---
## 6. Configuration photobooth-app
### Parametres critiques (config originale vs optimisee)
| Parametre | Avant (original) | Apres (optimise) | Impact |
|-----------|-----------------|------------------|--------|
| `logging_level` | `DEBUG` | `WARNING` | CPU+RAM en continu |
| `full_still_length` | 4608 | 2304 | /4 RAM par image |
| `CAPTURE_CAM_RESOLUTION` | 4608x3072 | 2304x1536 | /4 RAM capture |
| `PREVIEW_CAM_RESOLUTION` | 2304x1536 | 1152x768 | /4 RAM preview |
| `original_still_quality` | 100 | 90 | -35% taille fichiers |
| `thumbnail_still_length` | 960 | 480 | Moins de RAM galerie |
| `gpio_enabled` | false | true | GPIO natif photobooth-app |
| `secret_key` | `ThisIsTheDefaultSecret` | A changer ! | Securite |
### Justification des resolutions
- Camera Module 3 : capteur 4608x3072 (ratio 3:2)
- Cadres PNG : 2000x1333 (ratio 3:2)
- Impression Selphy 300dpi sur 100x150mm : besoin minimum 1770x1182 px
- **2304x1536 est suffisant** : au-dessus du cadre (2000px) et de l'impression (1770px)
- Ratio 3:2 conserve partout : pas de deformation ni de crop a l'impression
### Actions image (7 actions, config optimisee)
| # | Nom | Cadre | remove_background | Fond | show_button |
|---|-----|-------|-------------------|------|-------------|
| 0 | HnB normal | hnb cadre final.png | Non | Non | **Oui** |
| 1 | HnB etoile | hnb cadre final.png | Oui | background.jpg | Oui |
| 2 | HnB cailloux | hnb cadre final.png | Oui | Wall-with-large-and-small-stones.jpg | Non |
| 3 | HnB light | calque photos final.png | Oui | 2149243965.jpg | Non |
| 4 | Normal image | Aucun | Non | Non | Non |
| 5 | LULU | lulu-versaire2.png | Non | Non | Non |
| 6 | LULU etoile | lulu-versaire2.png | Oui | background.jpg | Non |
Actions supprimees (doublons) : `background stars`, `Hnb - Etoile - copy`
### Actions share (2 actions, config optimisee)
| # | Nom | Commande | Visible | Usage |
|---|-----|----------|---------|-------|
| 0 | Demande d'impression | `curl http://127.0.0.1:1880/api/photobooth-custom/ask_print?filename={filename}` | Oui | File d'attente SQLite via Node-RED |
| 1 | Impression directe | `/home/pi/photobooth-data/script/script_print.sh "{filename}" ...` | Non | Appelee par Node-RED quand l'admin valide |
Actions supprimees : `Pouet` (test), `Mailing action` (demo), `Printing copies` (doublon)
### QR Share
```json
{
"enabled": false,
"enabled_custom": true,
"share_custom_qr_url": "https://photomaton.lessapinsduweb.com/sharepage/#?url=https://photomaton.lessapinsduweb.com/media/full/{identifier}"
}
```
### Kiosk (Chromium)
Fichier : `~/Desktop/photobooth-app.desktop`
```ini
[Desktop Entry]
X-GNOME-Autostart-enabled=true
X-GNOME-Autostart-Delay=120
Terminal=false
Type=Application
Name=Photobooth-App
Exec=bash -c "sleep 60 && chromium --kiosk --accept-lang=fr-FR --incognito
--password-store=basic --disable-features=Translate,OverscrollHistoryNavigation
--noerrdialogs --disable-infobars --no-first-run --ozone-platform=wayland
--enable-features=OverlayScrollbar --start-maximized http://127.0.0.1:8083/"
StartupNotify=false
```
Points importants :
- `--ozone-platform=wayland` : Wayland natif (pas X11)
- Le binaire est `chromium` (pas `chromium-browser`) sous Trixie
- Le desktop file est dans `~/Desktop/`, pas dans `~/.config/autostart/`
---
## 7. Impression (Canon Selphy CP1300)
### Configuration CUPS
| Imprimante | Nom CUPS | Couleur |
|-----------|---------|---------|
| Selphy 1 | `Canon_SELPHY_CP1300_usb_blanche` | Blanche |
| Selphy 2 | `Canon_SELPHY_CP1300_usb_noire` | Noire |
Driver : Gutenprint (`printer-driver-gutenprint`)
### Script d'impression (`script_print.sh`)
Le script optimise fait :
1. **Verifie le ratio** de l'image. Si c'est deja du 3:2 (cas normal), pas de crop. Sinon, crop avec ImageMagick.
2. **Load-balancing** entre les 2 imprimantes :
- Si une est idle, utilise celle-la
- Si aucune n'est idle, choisit celle avec le moins de jobs en attente
- Fallback sur la blanche si les deux sont inaccessibles
3. **Envoie le job** via `lp -n COPIES -d PRINTER -o landscape -o fit-to-page`
4. **Nettoie** le fichier temporaire croppe apres 30 secondes
5. **Logs** via `logger` (visible avec `journalctl -t photomaton-print`)
### Commande d'impression directe (test)
```bash
lp -d Canon_SELPHY_CP1300_usb_blanche -o landscape -o fit-to-page /chemin/vers/photo.jpg
```
### Administration CUPS
- Interface web : `http://localhost:631`
- Via Node-RED dashboard : enable/disable imprimantes, cancel jobs
- Via script : `scripts/cups-cleanup.sh` (genere par `setup-printer.sh`)
---
## 8. Node-RED
### Role dans le systeme
Node-RED est **indispensable** dans le setup actuel. Il gere :
1. **Bouton physique** (GPIO23) : detection multi-clic via `button-events`, appel API photobooth-app
2. **Relay bouton** (GPIO12) : ON/OFF du bouton lumineux 12V pendant les captures
3. **NeoPixels** (GPIO18) : changement de couleur synchronise aux evenements photobooth
4. **Dashboard admin impression** : tableau des demandes, preview photos, boutons imprimer/annuler
5. **File d'attente SQLite** : stockage des demandes d'impression dans `photo-to-print.sqlite`
6. **Gestion CUPS** : etat imprimantes, enable/disable, cancel jobs
### Flows (onglets)
| Tab | Nom | Fonction |
|-----|-----|----------|
| 1 | Photomaton | GPIO bouton, relay, declenchement photo, selection mode |
| 2 | Flux 2 | Dashboard imprimantes (etat, enable/disable, jobs) |
| 3 | Flux 3 | Webhook events photobooth -> NeoPixels + relay bouton |
| 4 | Flux 4 | Controle NeoPixels direct (35 LEDs, GPIO18) |
| 5 | Sqlite | File d'attente impression (SQLite, dashboard, CRUD) |
### Endpoints HTTP (Node-RED)
| Endpoint | Methode | Usage |
|----------|---------|-------|
| `/api/photobooth/*` | GET | Webhook events photobooth (counting, capture, captured, finished) |
| `/api/photobooth-custom/ask_print` | GET | Demande d'impression (appelee par photobooth-app) |
| `/dashboard` | GET | Interface admin (impression, imprimantes, systeme) |
### Base SQLite
- Fichier : `/home/pi/photobooth-data/photo-to-print.sqlite`
- Table : `photoToPrint` (id, filename, uid, toPrint, printed, created_at)
- L'admin voit les photos en attente dans le dashboard avec preview et peut imprimer ou annuler
### Migration vers Python ?
**Non recommande.** Le gain serait de ~100 Mo de RAM, mais le cout de redeveloppement est eleve (dashboard, SQLite CRUD, GPIO multi-clic, NeoPixels sync, gestion CUPS). Les optimisations systeme et config liberent deja ~630 Mo sans rien recoder.
---
## 9. Analyse des problemes et optimisations
### Problemes rapportes
1. **Crashs frequents**
2. **Problemes d'impression**
3. **Memoire insuffisante (2 Go)**
### Consommation RAM mesuree (ps aux, au repos)
| Service | RAM (Mo) | % du total |
|---------|----------|-----------|
| **Chromium** (kiosk + processus fils) | **~580** | 40% |
| **Node-RED** | **171** | 12% |
| **photobooth-app** | **142** | 10% |
| **Zoraxy** | **99** | 7% |
| **Desktop inutile** (pcmanfm, wf-panel, portails, gvfsd...) | **~231** | 16% |
| Autres (labwc, pipewire, CUPS, dnsmasq, lighttpd, php-fpm...) | ~130 | 9% |
| Kernel + systeme | ~100 | 7% |
| **TOTAL** | **~1450** | **79%** |
RAM disponible au repos : **~725 Mo** -- mais ca chute fortement pendant les captures, surtout avec `remove_background`.
### Causes des crashs identifiees
| Cause | Impact | Correction |
|-------|--------|------------|
| `logging_level: DEBUG` | CPU+RAM constant, logs enormes | -> `WARNING` |
| Resolution capture 4608x3072 (14 Mpx) | ~56 Mo par image en RAM | -> 2304x1536 (~14 Mo) |
| `remove_background` (MODNet) sur 5/9 actions | +300-400 Mo RAM par traitement | Garder uniquement quand on change le fond |
| `original_still_quality: 100` | Fichiers JPEG 2x plus gros | -> 90 |
| Desktop inutile (pcmanfm, barre de taches, portails) | ~231 Mo gaspilles | Script `optimize-desktop.sh` |
| Swappiness a 60 | Le systeme swappe trop tot | -> 10 |
| Pas de swap fichier (seulement zram) | OOM kill si zram plein | Ajouter swapfile 1 Go |
### Plan d'optimisation
| Optimisation | Script | Gain RAM estime |
|-------------|--------|----------------|
| Desactiver desktop inutile | `optimize-desktop.sh` | **~231 Mo** |
| Reduire resolution capture | Config photobooth-app | **~42 Mo/capture** |
| Reduire resolution preview | Config photobooth-app | **~11 Mo** |
| `logging_level` DEBUG -> WARNING | Config photobooth-app | Variable (CPU + RAM) |
| JPEG quality 100 -> 90 | Config photobooth-app | -35% I/O disque |
| Desactiver services inutiles | `optimize-system.sh` | **~50 Mo** |
| Swappiness 60 -> 10 | `optimize-system.sh` | Moins de swap inutile |
| Swapfile 1 Go (filet de securite) | `optimize-system.sh` | Evite les OOM kills |
| Limiter Node-RED a 256 Mo (cgroup) | `optimize-system.sh` | Protection fuites memoire |
| Chromium optimise (process-per-site, JS heap) | Config kiosk | Reduction Chromium |
### Estimation apres optimisation
```
AVANT (mesure reelle):
Chromium ~580 Mo
Node-RED ~171 Mo
photobooth-app ~142 Mo
Zoraxy ~99 Mo
Desktop inutile ~231 Mo
Autres ~230 Mo
--------------------------------
TOTAL ~1453 Mo / 1843 Mo dispo
Marge disponible: ~390 Mo
Marge pendant capture: ~0 Mo (crash!)
APRES optimisation:
Chromium (optimise) ~400 Mo (options memoire)
Node-RED (cgroup 256 Mo) ~171 Mo (max 256 Mo)
photobooth-app ~142 Mo
Zoraxy ~99 Mo
Desktop inutile 0 Mo (desactive)
Autres (sans services inut) ~180 Mo
--------------------------------
TOTAL ~992 Mo / 1843 Mo dispo
Marge disponible: ~851 Mo
+ swapfile 1 Go en filet de securite
+ images 4x plus petites en RAM pendant capture
-> Suffisant meme avec remove_background (~300 Mo)
```
---
## 10. Guide de deploiement
### Prerequis
- Acces SSH au Raspberry Pi
- Copier le dossier `photomaton/` sur le Pi
### Etape 1 : Optimisation systeme
```bash
sudo bash scripts/optimize-system.sh
sudo reboot
```
Ce script :
- Ajoute un swapfile 1 Go (complement au zram existant)
- Baisse le swappiness de 60 a 10
- Configure gpu_mem a 128 Mo
- Desactive les services inutiles (bluetooth, ModemManager, rpcbind, apt timers...)
- Desactive le Bluetooth au niveau kernel
- Optimise les parametres memoire kernel (vfs_cache_pressure, dirty_ratio)
- Limite Node-RED a 256 Mo RAM (cgroup systemd)
- Optimise les parametres reseau
### Etape 2 : Optimisation desktop
```bash
sudo bash scripts/optimize-desktop.sh
sudo reboot
```
Ce script :
- Cree un autostart labwc minimal (que Chromium + pipewire)
- Desactive pcmanfm, wf-panel-pi, portails desktop, polkit, gvfsd
- Desactive ModemManager, accounts-daemon, colord, rpcbind, upower
- Reduit les workers php-fpm (RaspAP) a 2
**Reversible** : `sudo bash scripts/optimize-desktop.sh --restore`
### Etape 3 : Script d'impression
```bash
cp scripts/script_print.sh /home/pi/photobooth-data/script/script_print.sh
chmod +x /home/pi/photobooth-data/script/script_print.sh
```
### Etape 4 : Configuration photobooth-app
Deux options :
**Option A** : Appliquer via l'interface admin (`https://photomaton.lessapinsduweb.com/admin`)
- Modifier chaque parametre un par un en suivant le tableau de la section 6
**Option B** : Remplacer le fichier de config
- Copier `config/photobooth-config-optimized.json` dans le dossier de config de photobooth-app
- Supprimer les champs `_comment`, `_OPTI_*` (ce sont des annotations)
- Redemarrer photobooth-app
**Important** : Generer une vraie `secret_key` :
```bash
python3 -c "import secrets; print(secrets.token_hex(32))"
```
### Etape 5 : Services systemd (watchdog + maintenance)
```bash
# Service photobooth-app (utilisateur)
cp systemd/photobooth-app.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable photobooth-app
# Watchdog (systeme)
sudo cp systemd/photobooth-watchdog.service /etc/systemd/system/
sudo cp systemd/photobooth-watchdog.timer /etc/systemd/system/
# Editer les chemins dans les .service si necessaire
sudo systemctl daemon-reload
sudo systemctl enable photobooth-watchdog.timer
sudo systemctl start photobooth-watchdog.timer
# Maintenance quotidienne (systeme)
sudo cp systemd/photobooth-maintenance.service /etc/systemd/system/
sudo cp systemd/photobooth-maintenance.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable photobooth-maintenance.timer
sudo systemctl start photobooth-maintenance.timer
```
### Etape 6 : Verification
```bash
bash scripts/health-check.sh
```
### Quick wins immediats (sans script)
Si tu veux appliquer les corrections les plus impactantes maintenant sans lancer les scripts complets :
```bash
# 1. Baisser le swappiness (gain immediat)
sudo sysctl vm.swappiness=10
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-photomaton-swap.conf
# 2. Desactiver rpcbind (inutile)
sudo systemctl disable rpcbind.service rpcbind.socket
sudo systemctl stop rpcbind.service rpcbind.socket
# 3. Desactiver ModemManager (inutile)
sudo systemctl disable ModemManager.service
sudo systemctl stop ModemManager.service
# 4. Changer le logging_level dans photobooth-app admin
# http://localhost:8083/admin -> common -> logging_level -> WARNING
```
---
## 11. Fichiers du projet
```
photomaton/
scripts/
optimize-system.sh # Optimisation OS (swap, kernel, services)
optimize-desktop.sh # Desactiver le desktop inutile (~231 Mo)
setup-printer.sh # Configuration CUPS + Selphy CP1300
setup-photobooth.sh # Installation complete (master script)
script_print.sh # Script d'impression optimise (load-balancing)
health-check.sh # Watchdog / surveillance sante
maintenance.sh # Nettoyage automatique quotidien
config/
photobooth-config-backup.json # Config photobooth-app originale
photobooth-config-optimized.json # Config optimisee (avec annotations _OPTI_)
gpio-notes.conf # Documentation GPIO complete
zoraxy-notes.conf # Cartographie reseau Zoraxy
nodered-flows-backup.json # Reference backup flows Node-RED
systemd/
photobooth-app.service # Service robuste (auto-restart, limites RAM)
photobooth-watchdog.service # Health check automatique
photobooth-watchdog.timer # Toutes les 2 minutes
photobooth-maintenance.service # Nettoyage quotidien
photobooth-maintenance.timer # A 4h du matin
docs/
GUIDE-COMPLET.md # Ce fichier
ARCHITECTURE.md # Schema d'architecture
ANALYSE-CONFIG.md # Analyse detaillee des problemes
```
### Fichiers sur le Pi
```
/home/pi/
photobooth-data/
media/
processed_full/ # Photos traitees (pleine resolution)
script/
script_print.sh # Script d'impression
log/ # Logs quotidiens photobooth-app
photo-to-print.sqlite # File d'attente impression (Node-RED)
userdata/
hopnbloc/
frames/ # Cadres PNG 2000x1333 (ratio 3:2)
hnb cadre final.png
calque photos final.png
backgrounds/ # Fonds pour remove_background
Wall-with-large-and-small-stones.jpg
2149243965.jpg
LSDW/
lulu-versaire2.png # Cadre anniversaire
logo/logo.jpeg # Logo LSDW
demoassets/
backgrounds/background.jpg # Fond etoiles
frames/ # Cadres demo
.node-red/ # Node-RED
flows.json # Flows (5 onglets)
node_modules/
node-red-node-pi-gpio/ # GPIO nodes
node-red-node-pi-neopixel/ # NeoPixels nodes
zoraxy/
zoraxy # Binaire
start.sh # Script de demarrage
conf/proxy/ # Configs reverse proxy
ws2812/ # Ancien test NeoPixels (inactif)
Desktop/
photobooth-app.desktop # Autostart Chromium kiosk
```
---
## 12. Maintenance et surveillance
### Watchdog (health-check.sh)
Execute toutes les 2 minutes par `photobooth-watchdog.timer`, verifie :
- **Memoire** : alerte si < 100 Mo dispo, vide les caches si critique
- **Temperature CPU** : alerte si > 70C, erreur si > 80C
- **photobooth-app** : verifie si le service tourne ET si l'interface web repond (HTTP 200)
- **Imprimantes** : verifie CUPS, reactive les imprimantes desactivees, nettoie les jobs bloques
- **Espace disque** : alerte si > 80%, nettoyage d'urgence si > 90%
- **Camera** : verifie que la camera est detectee par libcamera
Si photobooth-app ne repond pas, le watchdog le relance automatiquement (max 3 tentatives).
### Maintenance quotidienne (maintenance.sh)
Execute tous les jours a 4h par `photobooth-maintenance.timer` :
- Nettoyage des vieux logs photobooth (> 7 jours)
- Nettoyage des logs systeme comprimes
- Limitation journald a 50 Mo
- Nettoyage des jobs CUPS bloques
- Reactivation des imprimantes desactivees
- Nettoyage cache apt
- Rapport d'etat (espace disque, nombre de photos, uptime)
### Service systemd photobooth-app
Le service `photobooth-app.service` inclut :
- `Restart=always` avec 5s de delai
- `MemoryMax=1500M` : kill si depasse 1.5 Go (protection OOM)
- `MemoryHigh=1200M` : avertissement a 1.2 Go
- `WatchdogSec=120` : watchdog integre systemd
- `StartLimitBurst=5` / `StartLimitIntervalSec=300` : max 5 redemarrages en 5 min
### Commandes utiles
```bash
# Logs photobooth-app
journalctl --user --unit=photobooth-app -n 200 --no-pager
# Logs impression
journalctl -t photomaton-print --no-pager
# Logs watchdog
journalctl -t photomaton-watchdog --no-pager
# Etat des services
systemctl --user status photobooth-app
systemctl status photobooth-watchdog.timer
systemctl status photobooth-maintenance.timer
# Etat imprimantes
lpstat -p
# Etat memoire
free -h
zramctl
# Etat des processus par RAM
ps aux --sort=-%mem | head -20
# Health check manuel
bash scripts/health-check.sh
```
---
## 13. Questions en suspens
- [x] ~~**NeoPixels doublon**~~ : RESOLU. uvicorn (:8081) est l'API backend de RaspAP (`/etc/raspap/api/`), pas les NeoPixels. Les NeoPixels sont geres uniquement par `neopix.py` via Node-RED. Le dossier `~/ws2812/` est un ancien test inactif.
- [ ] **Tester la config optimisee** en conditions reelles lors d'un event.
- [ ] **Generer une vraie `secret_key`** pour photobooth-app (remplacer `ThisIsTheDefaultSecret`).
- [ ] **Verifier le captive portal** : `address=/#/127.0.0.1` redirige tout domaine inconnu vers localhost du telephone (pas vers le Pi). Les telephones ne detecteront pas automatiquement un portail captif. Si besoin d'une page d'accueil, rediriger vers 10.3.141.1 a la place.
- [ ] **Verifier les cadres PNG** des autres actions (LULU, calque photos final.png) pour confirmer qu'ils sont aussi en ratio 3:2 et en resolution ~2000px.
+872
View File
@@ -0,0 +1,872 @@
# Photomaton LSDW - Guide d'installation from scratch
> Ce guide permet de remonter le photomaton completement a partir d'un Raspberry Pi 4 (2 Go) neuf.
> Reconstitue a partir de l'historique bash du Pi original.
> Derniere mise a jour : Juin 2026
---
## Table des matieres
1. [Prerequis](#1-prerequis)
2. [Installation de l'OS](#2-installation-de-los)
3. [Configuration initiale du Pi](#3-configuration-initiale-du-pi)
4. [Installation de photobooth-app](#4-installation-de-photobooth-app)
5. [Installation de RaspAP (hotspot WiFi)](#5-installation-de-raspap-hotspot-wifi)
6. [Installation de Zoraxy (reverse proxy)](#6-installation-de-zoraxy-reverse-proxy)
7. [Certificat TLS (Let's Encrypt + OVH)](#7-certificat-tls-lets-encrypt--ovh)
8. [Configuration des imprimantes (CUPS + Selphy)](#8-configuration-des-imprimantes-cups--selphy)
9. [Installation de Node-RED](#9-installation-de-node-red)
10. [NeoPixels (WS2812)](#10-neopixels-ws2812)
11. [Configuration du mode kiosk (Chromium)](#11-configuration-du-mode-kiosk-chromium)
12. [Optimisation systeme](#12-optimisation-systeme)
13. [Services systemd](#13-services-systemd)
14. [Verification finale](#14-verification-finale)
15. [Post-installation : contenu a restaurer](#15-post-installation--contenu-a-restaurer)
---
## 1. Prerequis
### Materiel necessaire
- Raspberry Pi 4 (2 Go RAM)
- Carte microSD (32 Go minimum, classe A2 recommandee)
- Camera Module 3 officielle Raspberry Pi
- Ecran HDMI
- Bouton physique lumineux 12V avec relay
- NeoPixels WS2812 (35 LEDs, strip)
- Canon Selphy CP1300 x2 (blanche + noire) + cables USB
- Cable Ethernet (pour l'installation initiale et les certificats)
- Clavier + souris (pour l'installation initiale)
### Logiciels sur le PC
- Raspberry Pi Imager (pour flasher la carte SD)
- Un client SSH (terminal, PuTTY, etc.)
---
## 2. Installation de l'OS
### Flasher la carte SD
1. Telecharger et installer [Raspberry Pi Imager](https://www.raspberrypi.com/software/)
2. Choisir l'OS : **Raspberry Pi OS (64-bit)** base sur Debian 13 Trixie
- Version **Desktop** (pas Lite, on a besoin de l'environnement graphique pour Chromium)
- Architecture **arm64**
3. Dans les options avancees (engrenage) :
- Hostname : `PiPhotobooth`
- Activer SSH (authentification par mot de passe)
- Utilisateur : `pi` / mot de passe : `[choisir un mot de passe]`
- Locale : `fr_FR.UTF-8`, timezone : `Europe/Paris`
- WiFi : ne pas configurer (on utilisera RaspAP)
4. Flasher la carte SD
### Premier demarrage
1. Inserer la carte SD, connecter l'ecran HDMI, le clavier, et le cable Ethernet
2. Demarrer le Pi
3. Attendre la fin du premier boot (peut prendre 2-3 minutes)
4. Se connecter en SSH : `ssh pi@PiPhotobooth.local`
---
## 3. Configuration initiale du Pi
### Mise a jour systeme
```bash
sudo apt update
sudo apt upgrade -y
```
### Configuration avec raspi-config
```bash
sudo raspi-config
```
Configurer :
- **System Options > Boot / Auto Login** : Desktop Autologin (B4)
- **Interface Options > Camera** : Activer (si demande)
- **Localisation Options** : Locale fr_FR.UTF-8, Timezone Europe/Paris
- **Advanced Options > Expand Filesystem** (si pas fait automatiquement)
### Desactiver les services inutiles
```bash
sudo systemctl disable bluetooth.service
sudo systemctl disable wg-quick@wg0.service 2>/dev/null
```
### Desactiver cloud-init (si present)
```bash
sudo touch /etc/cloud/cloud-init.disabled
```
### Configurer /etc/hosts
```bash
sudo nano /etc/hosts
```
Ajouter :
```
127.0.0.1 localhost
127.0.1.1 PiPhotobooth
10.3.141.1 photomaton.lessapinsduweb.com
10.3.141.1 photomaton-nodered.lessapinsduweb.com
10.3.141.1 photomaton-raspap.lessapinsduweb.com
10.3.141.1 photomaton-zoraxy.lessapinsduweb.com
```
Si cloud-init ecrase `/etc/hosts`, editer aussi le template :
```bash
sudo nano /etc/cloud/templates/hosts.debian.tmpl
```
### Redemarrer
```bash
sudo reboot
```
---
## 4. Installation de photobooth-app
### Dependances
```bash
sudo apt -y install ffmpeg libturbojpeg0 libgl1 libgphoto2-dev fonts-noto-color-emoji
sudo apt -y install libexif12 libgphoto2-6 libgphoto2-port12 libltdl7
sudo apt -y install python3-dev
sudo apt -y install pipx
sudo apt -y install imagemagick
```
### Installation via pipx
```bash
pipx ensurepath
# Fermer et rouvrir le terminal (ou source ~/.bashrc)
exit
```
```bash
ssh pi@PiPhotobooth.local
pipx install --system-site-packages photobooth-app --pip-args='--prefer-binary'
```
### Creer le dossier de donnees
```bash
mkdir ~/photobooth-data
```
### Verifier que la camera fonctionne
```bash
rpicam-hello --list-cameras -v
```
### Premier lancement (test)
```bash
cd ~/photobooth-data
photobooth --port 8083
```
Verifier sur `http://PiPhotobooth.local:8083` que l'interface fonctionne. Arreter avec Ctrl+C.
### Configuration de photobooth-app
Le service systemd est installe automatiquement par photobooth-app dans :
`~/.local/share/systemd/user/photobooth-app.service`
Editer pour configurer le port et les dependances :
```bash
nano ~/.local/share/systemd/user/photobooth-app.service
```
Contenu recommande :
```ini
[Unit]
Description=photobooth-app
After=zoraxy.service raspapd.service
[Service]
Type=simple
Restart=always
WorkingDirectory=/home/pi/photobooth-data
ExecStart=/home/pi/.local/share/pipx/venvs/photobooth-app/bin/python -O -m photobooth --port 8083
[Install]
WantedBy=default.target
```
Points importants :
- `After=zoraxy.service raspapd.service` : attend que Zoraxy et RaspAP soient prets
- `--port 8083` : port d'ecoute
- `Restart=always` : relance en cas de crash
Activer et demarrer :
```bash
systemctl --user daemon-reload
systemctl --user enable photobooth-app
systemctl --user start photobooth-app
```
Activer le linger (pour que le service demarre au boot sans login) :
```bash
sudo loginctl enable-linger pi
```
Verifier :
```bash
systemctl --user status photobooth-app
journalctl --user --unit=photobooth-app -n 50 --no-pager
```
### Configuration dans l'interface admin
Acceder a `http://PiPhotobooth.local:8083/admin` et configurer :
- **common** : `logging_level` -> `WARNING` (pas DEBUG !)
- **backends** : Camera Module 3, backend Picamera2, resolution 2304x1536
- **hardwareinputoutput** : `gpio_enabled` -> `true`
- **mediaprocessing** : `full_still_length` -> 2304, `preview_still_length` -> 1200
- **misc** : Changer `secret_key` (generer avec `python3 -c "import secrets; print(secrets.token_hex(32))"`)
Voir `config/photobooth-config-optimized.json` pour la config complete recommandee.
---
## 5. Installation de RaspAP (hotspot WiFi)
### Installation automatique
```bash
curl -sL https://install.raspap.com | bash
```
Suivre les instructions. Repondre oui aux questions par defaut.
Apres l'installation, le Pi redemarrera avec un hotspot WiFi actif.
### Configuration du hotspot
Acceder a l'interface RaspAP : `http://10.3.141.1:8082` (ou `http://PiPhotobooth.local:8082` via Ethernet)
Login par defaut : `admin` / `secret` (changer le mot de passe !)
Configurer :
- **Hotspot > Basic** :
- SSID : `Photomaton` (ou le nom souhaite)
- Security : WPA2
- Mot de passe WiFi : `[choisir]`
- **Hotspot > Advanced** :
- Country code : FR
- Channel : choisir un canal peu encombre
### Configuration DNS (dnsmasq)
Creer le fichier de resolution locale :
```bash
sudo nano /etc/dnsmasq.d/090_custom_local_hotspot.conf
```
Contenu :
```
address=/lessapinsduweb.com/10.3.141.1
address=/photomaton.lessapinsduweb.com/10.3.141.1
address=/#/127.0.0.1
```
Redemarrer dnsmasq :
```bash
sudo systemctl restart dnsmasq.service
```
Verifier :
```bash
dig @127.0.0.1 photomaton.lessapinsduweb.com A
# Doit repondre 10.3.141.1
```
### Changer le port lighttpd (si conflit)
Si lighttpd est sur le port 80 (conflit avec Zoraxy), le changer :
```bash
sudo nano /etc/lighttpd/lighttpd.conf
```
Changer `server.port = 80` en `server.port = 8082` (devrait deja etre fait par RaspAP).
---
## 6. Installation de Zoraxy (reverse proxy)
### Telecharger et installer
```bash
mkdir ~/zoraxy
cd ~/zoraxy
# Telecharger la derniere version arm64
# Verifier la derniere release sur https://github.com/tobychui/zoraxy/releases
wget https://github.com/tobychui/zoraxy/releases/download/v3.3.2/zoraxy_linux_arm64
mv zoraxy_linux_arm64 zoraxy
chmod +x zoraxy
```
### Creer le script de demarrage
```bash
nano ~/zoraxy/start.sh
```
Contenu :
```bash
#!/bin/bash
cd /home/pi/zoraxy
./zoraxy -port=:8001
```
```bash
chmod +x ~/zoraxy/start.sh
```
### Creer le service systemd
```bash
sudo nano /etc/systemd/system/zoraxy.service
```
Contenu :
```ini
[Unit]
Description=Zoraxy Reverse Proxy
After=network.target
[Service]
Type=simple
ExecStart=/home/pi/zoraxy/start.sh
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
```
```bash
sudo systemctl daemon-reload
sudo systemctl enable zoraxy.service
sudo systemctl start zoraxy.service
```
Verifier :
```bash
sudo systemctl status zoraxy.service
sudo ss -ltnp | grep zoraxy
```
### Configurer les proxies
Acceder a l'admin Zoraxy : `http://127.0.0.1:8001` (ou `http://PiPhotobooth.local:8001` via Ethernet)
Creer les 4 proxies :
**1. photomaton.lessapinsduweb.com -> 127.0.0.1:8083**
- WebSocket Custom Headers : ON
- Disable Chunked Transfer Encoding : ON
- Skip Certificate Validations : ON
**2. photomaton-nodered.lessapinsduweb.com -> 127.0.0.1:1880**
- Options par defaut
**3. photomaton-raspap.lessapinsduweb.com -> 127.0.0.1:8082**
- Options par defaut
**4. photomaton-zoraxy.lessapinsduweb.com -> 127.0.0.1:8001**
- Options par defaut
---
## 7. Certificat TLS (Let's Encrypt + OVH)
> Le certificat est necessaire pour HTTPS. Comme le Pi n'a pas d'acces internet permanent
> (WiFi isole), on utilise le challenge DNS via l'API OVH.
> Cette etape necessite un cable Ethernet connecte a internet.
### Installer certbot avec le plugin OVH
```bash
sudo apt install certbot # ou via venv si le paquet n'existe pas :
# sudo python3 -m venv /opt/certbot/
# sudo /opt/certbot/bin/pip install --upgrade pip
# sudo /opt/certbot/bin/pip install certbot certbot-dns-ovh
# sudo ln -s /opt/certbot/bin/certbot /usr/local/bin/certbot
```
### Configurer les credentials OVH
Creer les credentials API OVH sur https://api.ovh.com/createToken/
```bash
nano ~/.ovhapi
```
Contenu :
```ini
dns_ovh_endpoint = ovh-eu
dns_ovh_application_key = VOTRE_APP_KEY
dns_ovh_application_secret = VOTRE_APP_SECRET
dns_ovh_consumer_key = VOTRE_CONSUMER_KEY
```
```bash
chmod 600 ~/.ovhapi
```
### Generer le certificat
**Important** : Le Pi doit etre connecte a internet via Ethernet pour cette etape.
```bash
sudo certbot certonly \
--dns-ovh \
--dns-ovh-credentials ~/.ovhapi \
-d photomaton.lessapinsduweb.com \
-d photomaton-nodered.lessapinsduweb.com \
-d photomaton-raspap.lessapinsduweb.com \
-d photomaton-zoraxy.lessapinsduweb.com
```
Les certificats sont generes dans `/etc/letsencrypt/live/photomaton.lessapinsduweb.com/`.
### Importer dans Zoraxy
Dans l'admin Zoraxy (`http://127.0.0.1:8001`) :
1. Aller dans TLS / SSL
2. Importer le certificat :
- Certificate : contenu de `/etc/letsencrypt/live/photomaton.lessapinsduweb.com/fullchain.pem`
- Private Key : contenu de `/etc/letsencrypt/live/photomaton.lessapinsduweb.com/privkey.pem`
### Renouvellement
Le certificat expire tous les 90 jours. Pour renouveler :
1. Connecter le Pi a internet via Ethernet
2. Lancer : `sudo certbot renew`
3. Reimporter dans Zoraxy si necessaire
> Note : Ce n'est pas automatise car le Pi n'a pas d'acces internet permanent.
> Penser a renouveler avant chaque saison d'events.
---
## 8. Configuration des imprimantes (CUPS + Selphy)
### Installer les paquets
```bash
sudo apt -y install cups printer-driver-gutenprint cups-client
```
### Configurer les permissions
```bash
sudo usermod -aG lpadmin pi
sudo usermod -aG lp pi
```
### Configurer CUPS pour l'acces distant
```bash
sudo cupsctl --remote-any
sudo systemctl restart cups
```
### Gestion du driver USB
La Selphy CP1300 peut utiliser ipp-usb ou usblp. Pour eviter les conflits :
```bash
# Verifier si ipp-usb est installe
sudo apt list --installed | grep ipp
# Si necessaire, blacklister usblp pour utiliser ipp-usb
# (ou l'inverse selon ce qui fonctionne)
sudo nano /etc/modprobe.d/blacklist-usblp.conf
```
Contenu (si on utilise ipp-usb) :
```
# blacklist usblp
```
### Ajouter les imprimantes
1. Brancher les 2 Canon Selphy CP1300 en USB
2. Aller sur `http://localhost:631` (ou `https://photomaton-raspap.lessapinsduweb.com` via WiFi)
3. Administration > Add Printer
4. Selectionner l'imprimante USB Canon
5. Nommer :
- Premiere (blanche) : `Canon_SELPHY_CP1300_usb_blanche`
- Deuxieme (noire) : `Canon_SELPHY_CP1300_usb_noire`
6. Selectionner le driver Gutenprint
Verification :
```bash
lpstat -v
lpstat -p
```
### Installer le script d'impression
```bash
mkdir -p ~/photobooth-data/script
cp scripts/script_print.sh ~/photobooth-data/script/
chmod +x ~/photobooth-data/script/script_print.sh
```
### Tester l'impression
```bash
# Prendre une photo de test via photobooth-app, puis :
cd ~/photobooth-data/media/processed_full/
lp -d Canon_SELPHY_CP1300_usb_blanche -o landscape -o fit-to-page [nom_fichier].jpg
```
---
## 9. Installation de Node-RED
### Installation via le script officiel
```bash
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
```
Repondre oui aux questions. Le script installe Node.js et Node-RED, et cree le service systemd.
### Activer le service
```bash
sudo systemctl enable nodered.service
sudo systemctl start nodered.service
```
### Installer les nodes necessaires
Acceder a Node-RED : `http://PiPhotobooth.local:1880`
Dans le menu hamburger > Manage palette > Install, installer :
- `node-red-node-pi-gpio` (GPIO input/output)
- `node-red-node-pi-neopixel` (NeoPixels WS2812)
- `node-red-node-sqlite` (base SQLite)
- `node-red-dashboard` ou `@flowfuse/node-red-dashboard` (Dashboard v2)
- `node-red-contrib-button-events` (multi-clic bouton)
### Importer les flows
1. Dans Node-RED, menu hamburger > Import
2. Coller le contenu du fichier de flows (backup dans `config/nodered-flows-backup.json`)
3. Deploy
### Creer la base SQLite
```bash
sudo apt install sqlite3
```
La base est creee automatiquement par Node-RED au premier usage, mais on peut la creer manuellement :
```bash
sqlite3 ~/photobooth-data/photo-to-print.sqlite
```
```sql
CREATE TABLE photoToPrint(
id INT PRIMARY KEY,
filename TEXT NOT NULL,
uid TEXT NOT NULL,
toPrint INT DEFAULT 1,
printed BOOLEAN DEFAULT 0,
created_at TEXT NOT NULL DEFAULT current_timestamp
);
.quit
```
---
## 10. NeoPixels (WS2812)
### Cablage
- Data : GPIO18
- Alimentation : 5V + GND
- 35 LEDs
### Via Node-RED (methode utilisee)
Le node `node-red-node-pi-neopixel` gere les NeoPixels directement. Il lance un script Python en `sudo` :
```
/home/pi/.node-red/node_modules/node-red-node-pi-neopixel/neopix.py 35 0 pixels 100 true 0 18
```
Pas d'installation supplementaire requise au-dela du node Node-RED.
### Note : uvicorn sur le port 8081
Le processus uvicorn sur le port 8081 est l'**API backend de RaspAP** (`/etc/raspap/api/main.py`), pas un service NeoPixels. Il est lance automatiquement par RaspAP et ne doit pas etre desactive.
Le dossier `~/ws2812/` est un ancien test NeoPixels inactif (rien ne le lance). Il peut etre supprime si souhaite.
---
## 11. Configuration du mode kiosk (Chromium)
### Fichier desktop
```bash
nano ~/Desktop/photobooth-app.desktop
```
Contenu :
```ini
[Desktop Entry]
X-GNOME-Autostart-enabled=true
X-GNOME-Autostart-Delay=120
Terminal=false
Type=Application
Name=Photobooth-App
Exec=bash -c "sleep 60 && chromium --kiosk --accept-lang=fr-FR --incognito --password-store=basic --disable-features=Translate,OverscrollHistoryNavigation --noerrdialogs --disable-infobars --no-first-run --ozone-platform=wayland --enable-features=OverlayScrollbar --start-maximized http://127.0.0.1:8083/"
StartupNotify=false
```
### Points importants
- Le binaire est `chromium` (pas `chromium-browser`) sous Debian 13 Trixie
- `--ozone-platform=wayland` : utilisation native de Wayland (le compositeur est labwc)
- Le fichier est dans `~/Desktop/`, pas dans `~/.config/autostart/`
- Le `sleep 60` + `X-GNOME-Autostart-Delay=120` laissent le temps a photobooth-app de demarrer
- `--incognito` : pas de cache persistant, pas de popups "restore session"
### Lien symbolique pour autostart
```bash
sudo ln -s /home/pi/Desktop/photobooth-app.desktop /etc/xdg/autostart/photobooth.desktop
```
---
## 12. Optimisation systeme
### Scripts d'optimisation
Copier le dossier `photomaton/` sur le Pi, puis :
```bash
# Optimisation systeme (swap, kernel, services)
sudo bash scripts/optimize-system.sh
sudo reboot
# Optimisation desktop (desactiver composants inutiles, ~231 Mo)
sudo bash scripts/optimize-desktop.sh
sudo reboot
```
### Optimisations manuelles rapides
Si on ne veut pas lancer les scripts complets :
```bash
# Baisser le swappiness (60 -> 10)
sudo sysctl vm.swappiness=10
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-photomaton-swap.conf
# Desactiver rpcbind (inutile)
sudo systemctl disable rpcbind.service rpcbind.socket
sudo systemctl stop rpcbind.service rpcbind.socket
# Desactiver ModemManager (inutile)
sudo systemctl disable ModemManager.service
sudo systemctl stop ModemManager.service
# Desactiver bluetooth
sudo systemctl disable bluetooth.service
sudo systemctl stop bluetooth.service
# Ajouter un swapfile de securite (en complement de zram)
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon -p 10 /swapfile
echo '/swapfile none swap sw,pri=10 0 0' | sudo tee -a /etc/fstab
```
---
## 13. Services systemd
### Liste des services du photomaton
| Service | Type | Fichier | Gere par |
|---------|------|---------|----------|
| photobooth-app | User | `~/.local/share/systemd/user/photobooth-app.service` | pipx (auto-installe), After=zoraxy+raspapd |
| nodered | System | `/etc/systemd/system/nodered.service` | Script officiel Node-RED |
| zoraxy | System | `/etc/systemd/system/zoraxy.service` | Manuel (voir section 6) |
| cups | System | (pre-installe) | apt |
| hostapd | System | (pre-installe) | RaspAP |
| dnsmasq | System | (pre-installe) | RaspAP |
| lighttpd | System | (pre-installe) | RaspAP |
| dhcpcd | System | (pre-installe) | RaspAP |
### Services optionnels (surveillance)
```bash
# Watchdog (health check toutes les 2 minutes)
sudo cp systemd/photobooth-watchdog.service /etc/systemd/system/
sudo cp systemd/photobooth-watchdog.timer /etc/systemd/system/
# Editer ExecStart pour pointer vers le bon chemin de health-check.sh
sudo systemctl daemon-reload
sudo systemctl enable photobooth-watchdog.timer
sudo systemctl start photobooth-watchdog.timer
# Maintenance quotidienne (4h du matin)
sudo cp systemd/photobooth-maintenance.service /etc/systemd/system/
sudo cp systemd/photobooth-maintenance.timer /etc/systemd/system/
# Editer ExecStart pour pointer vers le bon chemin de maintenance.sh
sudo systemctl daemon-reload
sudo systemctl enable photobooth-maintenance.timer
sudo systemctl start photobooth-maintenance.timer
```
### Verification des services
```bash
# Tous les services actifs
sudo systemctl list-unit-files --type=service --state=enabled
# Etat de chaque service
systemctl --user status photobooth-app
sudo systemctl status nodered
sudo systemctl status zoraxy
sudo systemctl status cups
sudo systemctl status hostapd
sudo systemctl status dnsmasq
```
---
## 14. Verification finale
### Checklist
```bash
# 1. Tous les services tournent ?
systemctl --user status photobooth-app # active
sudo systemctl status nodered # active
sudo systemctl status zoraxy # active
sudo systemctl status cups # active
sudo systemctl status hostapd # active
sudo systemctl status dnsmasq # active
# 2. Tous les ports ecoutent ?
sudo ss -ltnp
# Attendu : 22, 53, 80, 443, 631, 1880, 5487, 8001, 8082, 8083
# 3. Camera detectee ?
rpicam-hello --list-cameras
# 4. Imprimantes detectees ?
lpstat -v
lpstat -p
# 5. DNS fonctionne ?
dig @127.0.0.1 photomaton.lessapinsduweb.com A
# Doit repondre 10.3.141.1
# 6. HTTPS fonctionne ?
curl -k https://photomaton.lessapinsduweb.com/
# (depuis le Pi lui-meme, ou depuis un telephone connecte au WiFi)
# 7. Memoire ?
free -h
# Verifier que Swap est present (zram + swapfile)
# 8. Health check complet
bash scripts/health-check.sh
```
### Test fonctionnel complet
1. Connecter un telephone au WiFi "Photomaton"
2. Appuyer sur le bouton physique (1 clic)
3. Verifier le countdown sur l'ecran
4. Verifier que la photo est prise et apparait dans la galerie
5. Scanner le QR code avec le telephone
6. Verifier que la photo se telecharge
7. Cliquer "Demander l'impression" dans la galerie
8. Sur le dashboard Node-RED (telephone) : valider l'impression
9. Verifier que la Selphy imprime correctement
---
## 15. Post-installation : contenu a restaurer
### Fichiers a copier depuis une sauvegarde
```bash
# Cadres et fonds
~/photobooth-data/userdata/hopnbloc/
~/photobooth-data/userdata/LSDW/
~/photobooth-data/userdata/demoassets/
# Script d'impression
~/photobooth-data/script/script_print.sh
# Configuration photobooth-app
~/photobooth-data/config/config.json
# Flows Node-RED
~/.node-red/flows.json
# Config Zoraxy (proxies)
~/zoraxy/conf/proxy/*.config
# Config dnsmasq custom
/etc/dnsmasq.d/090_custom_local_hotspot.conf
# Credentials OVH (pour certbot)
~/.ovhapi
```
### Sauvegarder le systeme
Pour eviter de devoir tout refaire, creer une image de la carte SD :
```bash
# Sur le PC (pas sur le Pi), avec la carte SD inseree :
sudo dd if=/dev/sdX of=photomaton-backup-$(date +%Y%m%d).img bs=4M status=progress
```
Ou utiliser `rpi-clone` pour cloner sur une deuxieme carte SD.