Naar de inhoud
BoilerBuddy

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 200 die niet van de API komt, zoals de inlogpagina van een hotspot, bevestigt niets. Controleer dat het antwoord JSON is met accepted.
  • 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 config en status. 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: true en 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:

  1. 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.
  2. Toch meten en de server laten corrigeren, met clock_synced: false en de monotone klok. Zie hieronder.
  3. 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. Echt false: "false" of 0 geeft invalid_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_at blijft 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_id of geen bruikbare mono_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.

Kom je er niet uit?

Stel je vraag via het contactformulier. We helpen je verder en maken deze pagina beter.

Neem contact op