Documentazione API device
Come inviare a TankTutor le letture di un sensore. È una funzione facoltativa, pensata per chi ha già sonde collegate.
Panoramica
Se hai dei sensori — ad esempio un TankTutor-PI o un misuratore di pH o conducibilità di terze parti — puoi inviare le misure alla tua vasca con una semplice richiesta HTTP. Non serve per usare TankTutor: puoi sempre inserire i parametri a mano o via chat.
Endpoint (il percorso è relativo all'indirizzo del sito): POST /api/devices/readings, con corpo JSON.
Chiavi device
Ogni richiesta è autenticata da una chiave device.
- Le chiavi si creano dalla pagina della vasca (
/my-tanks/[id]), nel pannello «Chiavi device». Serve un account. - Al massimo 4 chiavi attive per account, sommando tutte le vasche.
- Una chiave è legata a una sola vasca e non si può spostare.
- La chiave completa (
ttk_…) viene mostrata una sola volta, alla creazione: poi restano visibili solo i primi 8 caratteri. Conservala subito. - Revocare una chiave libera subito lo slot. Una chiave revocata riceve 401.
Autenticazione
Invia la chiave nell'header Authorization: Bearer ttk_YOUR_KEY (lo schema Bearer non distingue maiuscole e minuscole). Non serve nessun cookie di sessione.
Formato della richiesta
Il corpo è un oggetto JSON con un array readings.
| Campo | Tipo | Note |
|---|---|---|
readings | array | Array di 1–3 elementi. Un type non può comparire due volte. |
type | stringa | Uno tra temperature, ph, conductivity. |
value | numero | Numero finito. |
unit | stringa | Facoltativo, solo per temperature: "C" o "F" (default "C"). Il valore è sempre salvato in Celsius; il badge pubblico mostra i °F solo per gli account con lingua inglese. |
Se anche una sola voce non è valida, l'intera richiesta viene rifiutata con 400 e non viene salvato nulla.
{
"readings": [
{ "type": "temperature", "value": 25.4, "unit": "C" },
{ "type": "ph", "value": 7.2 }
]
}Risposte
| Stato | Corpo | Significato |
|---|---|---|
| 200 | {"saved": n} | Letture salvate; n è il numero di letture. |
| 400 | {"error":"invalid_device_readings"} | Corpo non valido (campo mancante, tipo sconosciuto o ripetuto, valore non numerico, unità non ammessa). Nulla è salvato. |
| 401 | {"error":"authentication_required"} | Header assente o malformato. |
| 401 | {"error":"invalid_device_key"} | Chiave sconosciuta o revocata. |
| 403 | {"error":"account_suspended"} | L'account è sospeso. |
| 429 | {"error":"rate_limited"} | Hai superato il limite di frequenza. Nulla è salvato. |
Limiti e affidabilità
Viene accettata al massimo una richiesta per finestra di tempo per utente, con tutte le sue chiavi sommate. Il default è 5 minuti; l'amministratore può cambiarlo, quindi non contare su un valore fisso.
Una risposta 429 non salva nulla: riprova dopo la finestra. Le letture di una richiesta sono salvate in blocco, tutte o nessuna.
Servizio in beta: nessun SLA garantito (disponibilità e tempi di risposta non sono vincolati).
Esempi
Gli indirizzi negli esempi usano l'origine da cui stai leggendo questa pagina.
curl -X POST https://tanktutor.it/api/devices/readings \
-H "Authorization: Bearer ttk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"readings":[{"type":"temperature","value":25.4,"unit":"C"},{"type":"ph","value":7.2}]}'import requests
resp = requests.post(
"https://tanktutor.it/api/devices/readings",
headers={"Authorization": "Bearer ttk_YOUR_KEY"},
json={
"readings": [
{"type": "temperature", "value": 25.4, "unit": "C"},
{"type": "ph", "value": 7.2},
]
},
timeout=10,
)
if resp.status_code == 200:
print("saved:", resp.json()["saved"])
elif resp.status_code == 429:
# Limite di frequenza: riprova dopo la finestra
print("rate limited")
else:
print("error:", resp.status_code, resp.json())