API
Messwerte senden
Messwerte in Stapeln von bis zu 1000 hochladen, die Antwort lesen, was bei jeder Ablehnung zu tun ist und was mit unbekannten Sensorcodes passiert.
Mit POST /device/readings lädst du Messwerte hoch, bis zu 1000 pro Stapel. Die Antwort sagt dir für jeden Messwert, was der Server damit gemacht hat. So weißt du genau, was du aus deinem Puffer löschen kannst.
Ein Stapel
{
"batch_uuid": "0d4f6c1e-8a51-4c43-9b6b-3c1f0f7a2e11",
"readings": [
{"sensor": "T1", "value": 61.4, "measured_at": "2026-10-08T11:59:00Z"},
{"sensor": "R2", "value": 10, "measured_at": "2026-10-08T11:59:00Z"},
{"sensor": "T3", "value": null, "quality": "no_response", "measured_at": "2026-10-08T11:59:00Z"}
]
}
| Feld | Pflicht | Regel |
|---|---|---|
readings |
ja | 1 bis 1000 Messwerte, als Liste |
batch_uuid |
nein | Eine UUID. Behalte sie bei, wenn du denselben Stapel erneut sendest |
clock |
nein | Uhr-Anker, nur für die Uhrkorrektur: siehe Puffern und die Uhr |
Pro Messwert:
| Feld | Pflicht | Regel |
|---|---|---|
sensor |
ja | Ein Code aus der Konfiguration des Geräts, etwa T1. 1 bis 16 Zeichen: Buchstaben, Ziffern, _, . und -. Groß- und Kleinschreibung zählt |
value |
ja, bei ok |
Eine Zahl. Darf null sein oder fehlen, wenn quality nicht ok ist |
quality |
nein | ok (Standard), sensor_fault, out_of_range oder no_response |
measured_at |
ja | Wann der Wert gelesen wurde, ISO 8601 mit Zeitzone |
clock_synced, boot_id, mono_ns |
nein | Nur für die Uhrkorrektur |
Doppelt senden schadet nicht
Ein Messwert ist eindeutig pro Gerät, Sensor und measured_at, auf die Sekunde genau. Sendest du ihn noch einmal, zählt er unter duplicates; der erste Wert bleibt, auch wenn der zweite abweicht. Einen Stapel nach einem Timeout erneut zu senden, ist daher sicher.
Du darfst batch_uuid und einen Idempotency-Key-Header mitsenden, aber der Server erkennt Duplikate an den Messwerten selbst.
Die Antwort
Ein Stapel, der als Ganzes gültig ist, bekommt 200, auch wenn einzelne Messwerte abgelehnt wurden:
{
"accepted": 2,
"duplicates": 0,
"unmapped": ["T9"],
"rejected": [{"index": 3, "reason": "measured_at_in_future", "retry": false}]
}
| Feld | Bedeutung |
|---|---|
accepted |
Neu gespeicherte Messwerte |
duplicates |
Messwerte, die der Server schon hatte, einschließlich Duplikaten innerhalb dieses Stapels |
unmapped |
Sensorcodes, die nicht zum Regelkreis des Geräts gehören. Diese Messwerte sind in Quarantäne und zählen nicht zu accepted |
rejected |
Pro abgelehntem Messwert: index (Position in readings, ab 0), reason und retry |
Lösche dann den ganzen Stapel aus deinem Puffer, außer den abgelehnten Messwerten mit retry: true. Die kommen in einen späteren Stapel.
422 bedeutet, dass der Stapel als Ganzes ungültig ist: kein oder ein leeres readings, mehr als 1000 Messwerte, oder eine ungültige batch_uuid oder clock. Die Antwort hat eine message und die errors pro Feld. Erneut senden hilft nicht: Leg den Stapel beiseite und such den Fehler.
Ablehnungen pro Messwert
reason |
Bedeutung | Was tun |
|---|---|---|
invalid_item |
Der Messwert ist kein Objekt, oder clock_synced ist nicht true oder false |
Ein Fehler in deiner Software: beheb ihn |
invalid_sensor |
sensor fehlt oder passt nicht zum Muster |
Beheb es |
invalid_value |
value ist keine Zahl, oder ihr Betrag liegt über 10⁹ |
Beheb es |
value_required |
quality ist ok (oder fehlt), aber es gibt keinen Wert |
Kein Wert? Sende no_response oder sensor_fault |
invalid_quality |
Unbekannter Wert für quality |
Nutze einen der vier Werte |
invalid_measured_at |
Kein gültiger ISO-8601-Zeitstempel mit Zeitzone, oder ein Datum, das es nicht gibt | Korrigiere das Format |
measured_at_in_future |
Mehr als 5 Minuten vor der Uhr des Servers | Die Uhr deines Geräts geht vor: Prüfe NTP |
measured_at_too_old |
Älter als 365 Tage | Nichts: Dieser Messwert lässt sich nicht mehr speichern |
clock_unsynced |
Mit einer nicht synchronisierten Uhr aufgenommen und nicht korrigierbar | Bei retry: true behalten und später senden. Siehe Puffern und die Uhr |
too_many_unknown_sensors |
Mehr als 16 verschiedene unbekannte Codes in diesem Stapel | Prüfe deine Sensorcodes |
unmapped_quota_exceeded |
Heute (UTC) schon 25.000 Messwerte in Quarantäne | Prüfe deine Sensorcodes |
batch_spans_too_many_days |
Der Messwert fällt in diesem Stapel auf einen achten Kalendertag (UTC) | Behalte ihn (retry: true) und sende ihn in einem späteren Stapel |
Nur batch_spans_too_many_days und clock_unsynced ohne synchronisierten Uhr-Anker kommen mit retry: true. Alle anderen Ablehnungen sind endgültig.
Unbekannte Sensoren
Ein Code, der nicht zum Regelkreis gehört, geht für 90 Tage in Quarantäne, damit sich ein Verkabelungs- oder Konfigurationsfehler nachvollziehen lässt.
- Diese Messwerte siehst du nicht in deinen Diagrammen und auch sonst nirgends im Portal, und du kannst sie nachträglich keinem Sensor zuordnen.
- Auf der Seite des Geräts erscheint unter Fehler in der API-Verbindung höchstens einmal pro Stunde eine Zeile mit der Zahl der abgelehnten Messwerte und den unbekannten Codes.
- Codes unterscheiden Groß- und Kleinschreibung:
t1ist nichtT1. - Ohne Regelkreis ist jeder Code unbekannt. Warte, bis die Konfiguration Sensoren hat, bevor du hochlädst: siehe Die Konfiguration abrufen.
Qualität
quality |
Wann | Was passiert |
|---|---|---|
ok |
Ein normaler Messwert | Zählt in Diagrammen, Mittelwerten, Minima und Maxima |
sensor_fault |
Der Sensor oder Regler meldet einen Fehler | Gespeichert, zählt nicht. Hält es an, folgt nach zehn Minuten die Meldung Sensorfehler |
out_of_range |
Gut gelesen, aber unmöglich | Sende den Wert. Gespeichert, zählt nicht |
no_response |
Der Sensor oder Regler hat nicht geantwortet | Wert null. Gespeichert, zählt nicht |
Sendet ein Sensor eine Weile keinen ok-Messwert (standardmäßig eine halbe Stunde), folgt die Meldung Sensor liefert keinen Messwert. Beide Meldungen kannst du pro Gerät unter Meldungen ausschalten.
Zeitstempel und Werte
measured_atdarf höchstens 5 Minuten in der Zukunft und 365 Tage in der Vergangenheit liegen. Der Server kürzt auf ganze Sekunden und speichert in UTC.- Ein Stapel umfasst höchstens 7 Kalendertage (UTC). Sendest du die ältesten zuerst, deckt ein Stapel höchstens ein, zwei Tage ab.
- Sende Zahlen, im Betrag nicht größer als 10⁹. Eine Zahl als Text (
"61.4") wird auch angenommen; anderer Text,trueoderfalseergibtinvalid_value. - Sende Ausgänge wie Pumpen und Ventile als Zahl, so wie der Regler sie meldet: siehe Dein eigenes BoilerBuddy bauen.
Alle Felder und Typen stehen in der API-Referenz.