fix: Update du readme

This commit is contained in:
2026-01-09 16:09:47 +00:00
parent fce468cf76
commit d9eda4746a

413
README.md
View File

@@ -1,28 +1,27 @@
# Pont Bascule Connector (Raspberry Pi) — FastAPI + Serial + Tailscale
API HTTP (FastAPI) qui pilote un pont bascule connecté en USB (port série) sur Raspberry Pi.
Objectif : permettre à une application/serveur distant dinterroger le pont bascule via réseau (Tailscale),
avec une contrainte stricte : **1 requête série à la fois**.
**Objectif :** permettre à une application/serveur distant d'interroger le pont bascule via réseau (Tailscale), avec une contrainte stricte : **1 requête série à la fois**.
---
## Fonctionnement global
```
Client (PC / serveur / app) --HTTP--> Raspberry Pi (FastAPI)
|
| 1 appel à la fois (lock)
v
Port série (/dev/ttyUSB0)
|
v
Pont bascule
|
| 1 appel à la fois (lock)
v
Port série (/dev/ttyUSB0)
|
v
Pont bascule
```
yaml
Copier le code
Accès distant :
**Accès distant :**
- via IP Tailscale `100.x.x.x` (VPN mesh)
- optionnellement via `tailscale serve` pour exposer lAPI sur le port 80 sans `:8000`
- optionnellement via `tailscale serve` pour exposer l'API sur le port 80 sans `:8000`
---
@@ -42,92 +41,108 @@ Accès distant :
## Installation (Raspberry Pi)
### 1) Récupérer le projet
```bash
cd ~
git clone <URL_DE_TON_REPO> pont-bascule-connector
cd pont-bascule-connector
2) Environnement Python
```
### 2) Environnement Python
Deux options :
Option A : venv global (recommandé si déjà en place)
#### Option A : venv global (recommandé si déjà en place)
bash
Copier le code
```bash
python3 -m venv /home/malio/venv
source /home/malio/venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
Option B : venv dans le projet
```
bash
Copier le code
#### Option B : venv dans le projet
```bash
python3 -m venv ./venv
source ./venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
Configuration série (.env)
Créer un fichier .env à la racine du projet :
```
bash
Copier le code
### 3) Configuration série (.env)
Créer un fichier `.env` à la racine du projet :
```bash
cd ~/pont-bascule-connector
nano .env
```
Exemple :
env
Copier le code
```env
SERIAL_PORT=/dev/ttyUSB0
SERIAL_BAUDRATE=9600
SERIAL_TIMEOUT_S=1.0
SERIAL_OPEN_DELAY_S=2.0
SERIAL_POST_WRITE_DELAY_S=0.5
Notes importantes
SERIAL_OPEN_DELAY_S=2.0 et SERIAL_POST_WRITE_DELAY_S=0.5 reproduisent le comportement du script Tkinter historique :
```
attente 2s après ouverture du port
**Notes importantes :**
envoi trame
- `SERIAL_OPEN_DELAY_S=2.0` et `SERIAL_POST_WRITE_DELAY_S=0.5` reproduisent le comportement du script Tkinter historique :
- attente 2s après ouverture du port
- envoi trame
- attente 0.5s
- lecture une seule fois de `in_waiting`
- Si ton port est `/dev/ttyACM0`, adapte `SERIAL_PORT`
attente 0.5s
### 4) Droits port série (dialout)
lecture une seule fois de in_waiting
Si ton port est /dev/ttyACM0, adapte SERIAL_PORT.
Droits port série (dialout)
Vérifier les devices :
bash
Copier le code
```bash
ls /dev/ttyUSB* 2>/dev/null || true
ls /dev/ttyACM* 2>/dev/null || true
dmesg | tail -n 30
Ajouter lutilisateur au groupe dialout :
```
bash
Copier le code
Ajouter l'utilisateur au groupe `dialout` :
```bash
sudo usermod -aG dialout malio
sudo reboot
Lancer lAPI (mode manuel)
bash
Copier le code
```
---
## Lancer l'API (mode manuel)
```bash
source /home/malio/venv/bin/activate # ou ./venv/bin/activate
uvicorn app.main:app --host 0.0.0.0 --port 8000
```
Test local :
bash
Copier le code
```bash
curl http://127.0.0.1:8000/health
Lancer lAPI au démarrage (systemd)
Créer le service :
```
bash
Copier le code
---
## Lancer l'API au démarrage (systemd)
### 1) Créer le service
```bash
sudo nano /etc/systemd/system/pont-bascule-api.service
```
Contenu (adapter les chemins si nécessaire) :
ini
Copier le code
```ini
[Unit]
Description=Pont bascule API (FastAPI)
After=network-online.target tailscaled.service
@@ -143,65 +158,78 @@ RestartSec=2
[Install]
WantedBy=multi-user.target
Activer et démarrer :
```
bash
Copier le code
### 2) Activer et démarrer
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now pont-bascule-api
sudo systemctl status pont-bascule-api --no-pager
Logs :
```
bash
Copier le code
### 3) Logs
```bash
journalctl -u pont-bascule-api -f
API — Endpoints
Santé
GET /health
```
---
## API — Endpoints
### Santé
**GET** `/health`
Exemple :
bash
Copier le code
```bash
curl http://127.0.0.1:8000/health
Dernière réponse (debug)
GET /last
```
Envoi trame “Esclave”
POST /send/esclave
### Dernière réponse (debug)
bash
Copier le code
**GET** `/last`
### Envoi trame "Esclave"
**POST** `/send/esclave`
```bash
curl -X POST http://127.0.0.1:8000/send/esclave
Envoi trame “DSD”
POST /send/dsd
```
bash
Copier le code
### Envoi trame "DSD"
**POST** `/send/dsd`
```bash
curl -X POST http://127.0.0.1:8000/send/dsd
Envoi trame custom (hex)
POST /send/custom
```
bash
Copier le code
### Envoi trame custom (hex)
**POST** `/send/custom`
```bash
curl -X POST http://127.0.0.1:8000/send/custom \
-H "Content-Type: application/json" \
-d '{"hex":"01 0D 0A"}'
Format de réponse
```
### Format de réponse
La réponse renvoie :
response_ascii : texte décodé ASCII (souvent le poids + infos)
response_hex : trame brute
duration_ms : durée de lopération
error : message derreur si problème
- `response_ascii` : texte décodé ASCII (souvent le poids + infos)
- `response_hex` : trame brute
- `duration_ms` : durée de l'opération
- `error` : message d'erreur si problème
Exemple (indicatif) :
json
Copier le code
```json
{
"ok": true,
"mode": "serial",
@@ -213,105 +241,130 @@ Copier le code
"duration_ms": 2600,
"error": null
}
Contrainte “1 appel à la fois” (important)
Le port série ne doit pas être utilisé en concurrence.
Si une requête est déjà en cours, lAPI renvoie :
HTTP 409
message BUSY
Accès à distance via Tailscale
1) Vérifier Tailscale
Sur le Raspberry :
bash
Copier le code
tailscale status
tailscale ip -4
Exemple : IP Tailscale du Pi 100.122.43.54.
2) Appeler lAPI via Tailscale (simple)
bash
Copier le code
curl http://100.122.43.54:8000/health
curl -X POST http://100.122.43.54:8000/send/esclave
3) Option recommandé : exposer sans port avec tailscale serve
Sur le Raspberry :
bash
Copier le code
sudo tailscale serve --http=80 localhost:8000
sudo tailscale serve status
Ensuite :
bash
Copier le code
curl http://100.122.43.54/health
curl -X POST http://100.122.43.54/send/esclave
4) SSH via Tailscale
bash
Copier le code
tailscale ssh malio@raspberrypi
Dépannage rapide
API down
bash
Copier le code
sudo systemctl status pont-bascule-api --no-pager
journalctl -u pont-bascule-api -n 100 --no-pager
Port série introuvable
bash
Copier le code
ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null
dmesg | tail -n 50
Permission refusée
bash
Copier le code
groups
# dialout doit apparaître
Pas de réponse
vérifier le baudrate
vérifier le port /dev/ttyUSB0 vs /dev/ttyACM0
augmenter SERIAL_POST_WRITE_DELAY_S (ex: 1.0) si la réponse arrive lentement
Sécurité recommandée (à faire)
Exposer lAPI uniquement via Tailscale :
faire écouter uvicorn en local seulement (--host 127.0.0.1)
utiliser tailscale serve comme reverse proxy
Ajouter un token API si besoin (header Authorization)
Ajouter une route /weight qui parse la chaîne response_ascii et renvoie weight + unit + ticket proprement.
yaml
Copier le code
```
---
## 3) Autres choses que je te recommande (vraiment utiles)
## Contrainte "1 appel à la fois" (important)
1) **Sécuriser lAPI**
Aujourdhui tu exposes `0.0.0.0:8000` → accessible depuis le LAN.
Si tu veux “Tailscale only” (recommandé) :
Le port série ne doit pas être utilisé en concurrence.
Si une requête est déjà en cours, l'API renvoie :
- **HTTP 409**
- message **BUSY**
---
## Accès à distance via Tailscale
### 1) Vérifier Tailscale
Sur le Raspberry :
```bash
tailscale status
tailscale ip -4
```
Exemple : IP Tailscale du Pi `100.122.43.54`.
### 2) Appeler l'API via Tailscale (simple)
```bash
curl http://100.122.43.54:8000/health
curl -X POST http://100.122.43.54:8000/send/esclave
```
### 3) Option recommandée : exposer sans port avec `tailscale serve`
Sur le Raspberry :
```bash
sudo tailscale serve --http=80 localhost:8000
sudo tailscale serve status
```
Ensuite :
```bash
curl http://100.122.43.54/health
curl -X POST http://100.122.43.54/send/esclave
```
### 4) SSH via Tailscale
```bash
tailscale ssh malio@raspberrypi
```
---
## Dépannage rapide
### API down
```bash
sudo systemctl status pont-bascule-api --no-pager
journalctl -u pont-bascule-api -n 100 --no-pager
```
### Port série introuvable
```bash
ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null
dmesg | tail -n 50
```
### Permission refusée
```bash
groups
# dialout doit apparaître
```
### Pas de réponse
- vérifier le baudrate
- vérifier le port `/dev/ttyUSB0` vs `/dev/ttyACM0`
- augmenter `SERIAL_POST_WRITE_DELAY_S` (ex: 1.0) si la réponse arrive lentement
---
## Sécurité recommandée (à faire)
1. **Exposer l'API uniquement via Tailscale :**
- faire écouter uvicorn en local seulement (`--host 127.0.0.1`)
- utiliser `tailscale serve` comme reverse proxy
2. **Ajouter un token API** si besoin (header `Authorization`)
3. **Ajouter une route `/weight`** qui parse la chaîne `response_ascii` et renvoie `weight` + `unit` + `ticket` proprement.
---
## Autres recommandations (vraiment utiles)
### 1) Sécuriser l'API
Aujourd'hui tu exposes `0.0.0.0:8000` → accessible depuis le LAN.
Si tu veux "Tailscale only" (recommandé) :
- Dans systemd : `--host 127.0.0.1`
- Et tu actives `tailscale serve --http=80 localhost:8000`
2) **Ajouter une route `/weight`**
Tu menvoies 1 exemple de `response_ascii` (exact) et je te code un parseur robuste qui sort :
### 2) Ajouter une route `/weight`
Tu m'envoies 1 exemple de `response_ascii` (exact) et je te code un parseur robuste qui sort :
```json
{"weight": 12.34, "unit": "kg", "ticket": "000123", "raw": "..."}
Port série stable (udev)
Si ton port passe parfois de /dev/ttyUSB0 à /dev/ttyUSB1, on peut créer une règle udev pour avoir un nom fixe, genre /dev/pontbascule.
{
"weight": 12.34,
"unit": "kg",
"ticket": "000123",
"raw": "..."
}
```
Healthcheck matériel
Ajouter une route GET /serial/info qui vérifie :
### 3) Port série stable (udev)
port existe
user a accès
bridge non-busy
Si ton port passe parfois de `/dev/ttyUSB0` à `/dev/ttyUSB1`, on peut créer une règle udev pour avoir un nom fixe, genre `/dev/pontbascule`.