API
Bufferen en de klok
Metingen lokaal bewaren en op volgorde versturen, inhalen na een storing binnen de limieten, en metingen van voor de kloksynchronisatie laten corrigeren.
Zo blijft je apparaat meten als het internet wegvalt, haal je daarna alles in zonder metingen kwijt te raken, en zet de server metingen van vóór de kloksynchronisatie alsnog op de juiste tijd.
Eerst bewaren, dan versturen
Schrijf elke meting eerst naar een lokale buffer, bijvoorbeeld SQLite, en verstuur van daaruit: oudste eerst, in batches van hooguit 1000. Dan wacht het meten nooit op het netwerk.
| Antwoord | Wat je doet |
|---|---|
200 |
Haal de batch uit de buffer, behalve de afgewezen metingen met retry: true. Die gaan mee in een volgende batch |
Geen antwoord, time-out, 429 of 5xx |
Houd de batch en stuur hem later opnieuw, met dezelfde batch_uuid. Wat de server al had, telt als duplicates |
422 |
De batch klopt als geheel niet en opnieuw sturen helpt niet. Zet hem apart, zodat hij de rest niet blokkeert, en zoek de fout |
401 |
Houd alles. Met een nieuw token kun je alsnog versturen |
- Een
200die niet van de API komt, zoals de inlogpagina van een hotspot, bevestigt niets. Controleer dat het antwoord JSON is metaccepted. - Buffer vol? Gooi de oudste metingen weg, niet de nieuwste. Ter vergelijking: de BoilerBuddy Alpo bewaart er hooguit een miljoen, ruim twee maanden bij negen sensoren per minuut.
Inhalen na een storing
Per token mag je 10 batches van 1000 metingen per minuut uploaden. Een week zonder internet bij 8 sensoren die elke minuut meten, is 8 × 1440 × 7 = 80 640 metingen: op volle snelheid ongeveer negen minuten inhalen.
- Laat binnen je 60 verzoeken per minuut ruimte voor
configenstatus. Hooguit 8 batches van 500 per minuut is een veilige maat. - Metingen ouder dan 365 dagen krijgen
measured_at_too_old. - Valt een meting op een achtste kalenderdag (UTC) in de batch, dan krijgt hij
retry: trueen gaat hij mee in de volgende. Wie op volgorde verstuurt, haalt dat niet. - Meer dan 5 minuten in de toekomst wordt afgewezen. Een klok die voorloopt, kost je dus metingen: houd hem gelijk met NTP.
De klok
Zelfbouwhardware zoals een Raspberry Pi of ESP32 heeft meestal geen klok met batterij. Na het aanzetten klopt de tijd niet (1970, of het moment van uitschakelen) tot NTP de klok gelijk zet. Je kunt dan:
- Wachten met meten tot de klok gelijk loopt. Het minste werk: je mist alleen de eerste minuut of zo. Het ESP32-voorbeeld doet het zo.
- Toch meten en de server laten corrigeren, met
clock_synced: falseen de monotone klok. Zie hieronder. - De
Date-header uit elk antwoord van de server gebruiken als tijdbron voor het klokanker, zolang NTP nog niet gesynchroniseerd is.
Hoe de correctie werkt
Stuur bij elke meting van vóór de synchronisatie mee:
clock_synced: false. Echtfalse:"false"of0geeftinvalid_item.boot_id: een id van deze opstart. Op Linux staat die in/proc/sys/kernel/random/boot_id; op een microcontroller maak je bij elke start een willekeurige.mono_ns: de monotone klok in nanoseconden op het moment van meten. Die telt vanaf het opstarten en springt nooit.measured_atblijft verplicht en moet een geldige tijd zijn. Stuur wat je klok zegt.
Bij de batch hoort dan een klokanker: de klok op het moment van versturen.
"clock": {"boot_id": "4b8e7c1d-…", "synced": true, "sent_at": "2026-10-15T09:31:02Z", "sent_mono_ns": 72000000000}
De server rekent measured_at = sent_at − (sent_mono_ns − mono_ns). Dat lukt alleen als het anker synced: true heeft, de boot_id van de meting gelijk is aan die van het anker, en mono_ns een geheel getal is dat niet groter is dan sent_mono_ns. Daarna gelden de gewone grenzen: hooguit 5 minuten vooruit, niet ouder dan 365 dagen.
Lukt het niet, dan krijgt de meting clock_unsynced:
- Geen anker, of een anker met
synced: false:retry: true. Stuur de meting opnieuw zodra je klok gelijk loopt. Zolang het apparaat niet herstart, kan de server hem dan nog plaatsen. - Een gesynchroniseerd anker, maar een andere
boot_idof geen bruikbaremono_ns:retry: false. De meting is van een eerdere opstart en niet meer te plaatsen. Stuur ongesynchroniseerde metingen dus snel na de synchronisatie, voor een herstart.
Een voorbeeld
Een apparaat start op met de klok op 1970. Na 12 seconden meet het T1: 48,2 °C, met klok 1970-01-01T00:00:12Z en monotone klok 12 000 000 000 ns. Na 40 seconden zet NTP de klok gelijk, en na 72 seconden gaat de batch weg:
{
"clock": {"boot_id": "4b8e7c1d-2f3a-4c5b-8d6e-9f0a1b2c3d4e", "synced": true,
"sent_at": "2026-10-15T09:31:02Z", "sent_mono_ns": 72000000000},
"readings": [
{"sensor": "T1", "value": 48.2, "measured_at": "1970-01-01T00:00:12Z",
"clock_synced": false, "boot_id": "4b8e7c1d-2f3a-4c5b-8d6e-9f0a1b2c3d4e",
"mono_ns": 12000000000}
]
}
Het verschil is 72 − 12 = 60 seconden, dus de meting komt op 09:31:02 − 60 s = 2026-10-15T09:30:02Z.
Was de batch al na 30 seconden verstuurd, met een anker met synced: false, dan was het antwoord {"index": 0, "reason": "clock_unsynced", "retry": true} geweest. Het apparaat houdt de meting dan, en na 72 seconden lukt het alsnog.