# API IoT — ArniAmica

Contratto di integrazione tra i dispositivi installati nelle arnie e la piattaforma.
Tutto ciò che arriva da qui compare **in tempo reale** nell’area riservata degli adottanti
(le pagine ricevono gli aggiornamenti tramite Server-Sent Events, senza ricaricare).

- **Base URL**: `https://www.arniamica.it/api/iot/v1` (in locale: `http://localhost:3000/api/iot/v1`)
- **Formato**: JSON UTF-8
- **Autenticazione**: una chiave per arnia, nell’header `Authorization: Bearer <device_key>`
  (in alternativa `X-Device-Key: <device_key>`). Le chiavi si leggono e si rigenerano da **Gestione → Arnie e dispositivi IoT**.
- La chiave identifica l’arnia: il device non deve inviare l’id dell’arnia.

---

## 1. Verifica connessione

```
GET /ping
Authorization: Bearer dev_xxxxxxxx
```
Risposta `200`:
```json
{ "ok": true, "hive": "Arnia Acacia", "server_time": 1790000000000 }
```
Utile all’avvio del device anche per sincronizzare l’orologio.

## 2. Invio misure

```
POST /telemetry
Authorization: Bearer dev_xxxxxxxx
Content-Type: application/json
```

Lettura singola (`ts` facoltativo: se assente vale l’ora di ricezione):
```json
{
  "ts": "2026-09-27T14:05:00Z",
  "metrics": {
    "temp_in": 34.6,
    "temp_out": 21.3,
    "hum_in": 58,
    "hum_out": 64,
    "weight": 42.315,
    "activity": 112,
    "sound": 52.4,
    "battery": 91
  }
}
```

Invio a lotti (es. dopo un periodo senza rete, max 5000 letture per richiesta):
```json
{ "readings": [ { "ts": 1790000000000, "metrics": { "temp_in": 34.5 } }, { "ts": 1790000300000, "metrics": { "temp_in": 34.6 } } ] }
```

Risposta `200`: `{ "ok": true, "stored": 8 }`

### Metriche riconosciute

| chiave     | significato                               | unità   |
|------------|-------------------------------------------|---------|
| `temp_in`  | temperatura nel nido / coprifavo          | °C      |
| `temp_out` | temperatura esterna                       | °C      |
| `hum_in`   | umidità relativa interna                  | %       |
| `hum_out`  | umidità relativa esterna                  | %       |
| `weight`   | peso totale arnia (bilancia)              | kg      |
| `activity` | api in transito all’ingresso              | api/min |
| `sound`    | livello sonoro del ronzio                 | dB      |
| `battery`  | carica batteria del nodo                  | %       |

**Nuovi sensori** non richiedono modifiche al database: basta inviare una nuova chiave in
`snake_case` minuscolo (es. `co2`, `hum_brood`, `freq_peak`). Viene salvata e mostrata subito;
per darle nome, unità e colore aggiungerla a `METRICS` in `server/config.js`.

`ts` accetta millisecondi epoch, secondi epoch o stringa ISO 8601. Timestamp più di 5 minuti
nel futuro vengono rifiutati (controllare l’orologio del device).

## 3. Immagine webcam (snapshot)

Per telecamere semplici (es. ESP32-CAM) che scattano una foto ogni N secondi:
```
POST /snapshot
Authorization: Bearer dev_xxxxxxxx
Content-Type: image/jpeg

<byte dell’immagine, max 5 MB>
```
Risposta: `{ "ok": true, "ts": 1790000000000 }`. L’area riservata aggiorna l’immagine in automatico.

In alternativa, se la telecamera espone un flusso continuo (MJPEG, video, YouTube Live…),
configurarne l’URL da **Gestione → Configura webcam**: in quel caso gli snapshot non servono.
Senza né flusso né snapshot, l’area riservata mostra un’anteprima simulata.

## 4. Eventi e avvisi

Il device può segnalare eventi rilevati automaticamente; compaiono nel diario dell’arnia.
```
POST /events
Authorization: Bearer dev_xxxxxxxx
Content-Type: application/json

{ "type": "swarm", "title": "Possibile sciamatura", "body": "Calo di peso di 1,8 kg in 20 minuti." }
```
Tipi con icona dedicata: `alert`, `swarm`, `visit`, `harvest`, `treatment`, `feeding`.

## Errori

| codice | quando                                        |
|--------|-----------------------------------------------|
| 400    | JSON o valori non validi (il messaggio spiega quale) |
| 401    | chiave device mancante o errata               |
| 413    | payload troppo grande                         |
| 415    | Content-Type errato                           |

## Raccomandazioni per il firmware

- Frequenza consigliata: una lettura ogni 1–5 minuti; la webcam ogni 30–60 s.
- In assenza di rete, accumulare le letture in memoria e reinviarle con `readings`.
- Riprovare con backoff esponenziale in caso di errore 5xx o di rete; **non** riprovare su 4xx.
- Solo HTTPS: la chiave viaggia nell’header.

Esempio completo funzionante: `scripts/device-example.js` (`npm run device -- <device_key>`).
