first commit
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user