# 📷 Documentation ESP32-CAM — API HTTP

Firmware embarqué sur **ESP32-CAM AI-Thinker** (OV2640, 8MB PSRAM).

---

## 🌐 Connexion

La caméra se connecte automatiquement au WiFi configuré dans `/sdcard/config.ini`.
L'adresse IP est affichée au démarrage dans les logs série.

```
http://192.168.1.109/
```

> **Astuce** : Ouvrez `http://<IP>/` dans votre navigateur pour voir la liste interactive de toutes les routes.

---

## 🔌 Routes API

### `GET /`
**Page d'accueil HTML** — Liste toutes les commandes disponibles avec des liens cliquables.

---

### `GET /capture`
**Prendre une photo** et la retourner en JPEG.

| Réponse | Type |
|---------|------|
| Image JPEG | `image/jpeg` |

**Exemple :**
```
http://192.168.1.109/capture
```

---

### `GET /status`
**Statut complet de la caméra** en JSON.

| Champ | Description |
|-------|-------------|
| `status` | `"ok"` si tout fonctionne |
| `rssi` | Signal WiFi actuel en dBm |
| `resolution_id` | Index de résolution actif (0-4) |
| `resolution` | Nom de la résolution (ex: "XGA") |
| `hmirror` | `1` si miroir horizontal actif, sinon `0` |
| `vflip` | `1` si miroir vertical actif, sinon `0` |
| `log_count` | Nombre d'événements dans le journal |

**Exemple de réponse :**
```json
{
  "status": "ok",
  "rssi": -58,
  "resolution_id": 3,
  "resolution": "XGA (1024x768)",
  "hmirror": 0,
  "vflip": 0,
  "log_count": 12
}
```

---

### `GET /list_resolutions`
**Liste des résolutions disponibles.**

**Réponse :**
```
0:QVGA(320x240)
1:VGA(640x480)
2:SVGA(800x600)
3:XGA(1024x768) [défaut]
4:UXGA(1600x1200)
```

---

### `GET /set_resolution?id=<N>`
**Changer la résolution** de la caméra à chaud.

| Paramètre | Type | Obligatoire |
|-----------|------|-------------|
| `id` | entier (0–4) | ✅ |

| `id` | Résolution | Dimensions | Notes |
|------|------------|------------|-------|
| 0 | QVGA | 320 × 240 | Très légère |
| 1 | VGA | 640 × 480 | Bonne fluidité |
| 2 | SVGA | 800 × 600 | — |
| **3** | **XGA** | **1024 × 768** | **Défaut au démarrage** |
| 4 | UXGA | 1600 × 1200 | Lourde, peut provoquer des timeouts |

**Exemples :**
```
http://192.168.1.109/set_resolution?id=1   → VGA
http://192.168.1.109/set_resolution?id=3   → XGA (défaut)
http://192.168.1.109/set_resolution?id=4   → UXGA
```

**Réponse :**
```
Résolution mise à jour : id=3
```

> 💾 **Persistance** : Le choix est sauvegardé en mémoire NVS et rechargé automatiquement au démarrage.

---

### `GET /flip?h=<0|1>&v=<0|1>`
**Symétries image** — Miroir horizontal et/ou vertical.

| Paramètre | Valeur | Description |
|-----------|--------|-------------|
| `h` | `0` ou `1` | Miroir horizontal (gauche ↔ droite) |
| `v` | `0` ou `1` | Miroir vertical (haut ↔ bas) |

> Au moins un des deux paramètres est obligatoire.

**Exemples :**
```
http://192.168.1.109/flip?h=1          → Miroir horizontal activé
http://192.168.1.109/flip?v=1          → Miroir vertical activé
http://192.168.1.109/flip?h=1&v=1     → Les deux activés (image retournée)
http://192.168.1.109/flip?h=0&v=0     → Tout désactivé (image normale)
```

**Réponse :**
```
Flip appliqué : h_mirror=ON, v_flip=OFF
```

> 💾 **Persistance** : Ces réglages sont sauvegardés en mémoire NVS et rechargés automatiquement au démarrage.

---

### `GET /logs?type=<photo|wifi|flip|resolution>`
**Journal d'événements** interactif.
- Sans paramètre : Affiche tous les logs.
- Paramètre `type` : Filtre par catégorie.

### `GET /logs/clear`
**Effacer le journal** et rediriger vers `/logs`.

---

### `GET /scan`
**Lancer un scan WiFi manuel**. Détecte tous les réseaux à portée et met à jour la liste sur la page d'accueil. Redirige vers `/`.

---

## 🛠️ Démarrage et configuration

### Prérequis

- Carte SD FAT32 avec un fichier `/sdcard/config.ini`
- Partition NVS `storage` flashée avec la clé AES (via `config_tool.py`)

### Format `config.ini`

```ini
[system]
hostname=esp32-camera-1  # Nom apparaissant sur le réseau (DHCP)

[wifi_1]
ssid=MonWifi
pass=<mot_de_passe_chiffré_AES256>

[wifi_2]
ssid=AutreWifi
pass=<mot_de_passe_chiffré_AES256>
```

> [!TIP]
> Le firmware supporte le **Roaming automatique**. Si le signal tombe en dessous de -80dBm, la caméra cherchera automatiquement un meilleur réseau parmi ceux listés dans la configuration.

### Chiffrement des mots de passe

```bash
cd timelapse_firmware/
source venv/bin/activate
python3 config_tool.py
```

---

## 🔧 Environnement de développement

### Initialiser l'environnement

```bash
source ~/env_gravity/timelapse_firmware/esp_env.sh
```

### Commandes disponibles

| Commande | Action |
|----------|--------|
| `esp-build` | Compiler le firmware |
| `esp-flash` | Flasher la carte (IO0→GND requis) |
| `esp-monitor` | Voir les logs série |
| `esp-all` | Compiler + flasher + moniteur |
| `esp-clean` | Nettoyer le build |
| `esp-port` | Lister les ports USB disponibles |
| `esp-kill` | Libérer le port `/dev/ttyUSB0` si bloqué |

### Flasher la carte

> ⚠️ Sur l'ESP32-CAM AI-Thinker, le mode flash n'est pas automatique.

1. Relier la broche **IO0** à **GND** (jumper)
2. Appuyer sur **RESET**
3. Lancer `esp-all` ou `esp-flash`
4. Dès que les pourcentages s'affichent → retirer le jumper IO0-GND
5. Une fois le flash terminé → appuyer sur **RESET** pour démarrer normalement

---

## 📊 Caractéristiques matérielles

| Composant | Détail |
|-----------|--------|
| MCU | ESP32-D0WDQ6-V3 (rev 3.1) |
| Capteur | OV2640 |
| PSRAM | 8MB (4MB mappés) |
| Flash | 4MB |
| WiFi | 802.11 b/g/n (WPA2-PSK) |
| Débit | 460800 baud (flash) / 115200 baud (monitor) |

---

## ❗ Dépannage

| Symptôme | Cause | Solution |
|----------|-------|----------|
| `cam_hal: FB-OVF` | Buffer overflow caméra | Normal au démarrage, disparaît après |
| `Failed to get frame: timeout` | Résolution trop élevée | Réduire avec `/set_resolution?id=2` |
| `URI '/' not found` | Mauvaise URL | Utiliser les routes documentées ci-dessus |
| Port USB bloqué | Processus zombie | `esp-kill` |
| `Wrong boot mode detected` | IO0 encore relié à GND | Retirer le jumper et faire RESET |
