Zum Inhalt springen

Zustandsdaten aus einem Batteriemanagementsystem senden

Melden Sie Messwerte wie Ladezustand oder Vollzyklen mit updateCondition und lesen Sie, was übernommen, übersprungen und neu veröffentlicht wurde.

Ein Batteriemanagementsystem (BMS), ein Servicewerkzeug oder eine Monitoring-Plattform meldet seine Messwerte mit updateCondition. BatteryPass übernimmt die Werte als Messungen ohne Prüfschritt, speichert sie mit Messzeitpunkt und source api, ergänzt den Lebenszyklus der Einheit um ein Ereignis condition_update, das den Schlüssel nennt (api_key), und veröffentlicht den Pass nach der Regel Ihrer Organisation neu. Die Grundlagen stehen unter Zustand und Lebenszyklus.

Bevor Sie beginnen

  • Ein Schlüssel mit dem Scope condition. Eine Eigentümerin oder ein Eigentümer erstellt ihn im Portal unter Einstellungen → API-Schlüssel. Lesen (etwa getCondition oder listBatteries) braucht den Scope read; geben Sie dem Schlüssel beide Scopes, wenn das System beides tut. Mehr unter Schlüssel sicher verwalten.
  • Die ID der Einheit. Speichern Sie sie in Ihrem System neben der Seriennummer, etwa mit Einheiten abgleichen, oder suchen Sie sie mit listBatteries?serial_prefix=.
  • Die Felder. Angenommen werden nur die dynamischen Felder des Feldregisters (Abschnitt condition), und nur die, die für die Batteriekategorie der Einheit gelten. getCondition nennt sie mit ihren aktuellen Werten und zeigt die Regel für die Neuveröffentlichung:
cURL
curl -sS "$BATTERYPASS_URL/api/v1/batteries/0192a3f0-5b7c-7d21-8e4f-6a2b9c1d3e5f/condition" \
  -H "Authorization: Bearer $BATTERYPASS_API_KEY"
200 (gekürzt)
{
  "battery_id": "0192a3f0-5b7c-7d21-8e4f-6a2b9c1d3e5f",
  "field_keys": [
    "condition.state_of_charge",
    "condition.remaining_capacity",
    "condition.capacity_fade",
    "condition.number_of_full_cycles"
  ],
  "values": [
    {
      "field_key": "condition.number_of_full_cycles",
      "value": 412,
      "revision": 6,
      "source": "api",
      "review_status": "approved",
      "measured_at": "2026-10-23T06:00:00Z",
      "recorded_at": "2026-10-23T06:00:04Z",
      "registry_version": "0.5.0",
      "checks": []
    }
  ],
  "republish": "immediate"
}

Ein Update senden

PATCH /api/v1/batteries/{batteryId}/condition mit einem JSON-Body:

valuesobject[]bodyerforderlich

1 bis 50 Werte, jedes Feld höchstens einmal.

measured_atdate-timebody
Der Messzeitpunkt aller Werte ohne eigenen.
notestringbody
Höchstens 500 Zeichen; wird die Beschreibung des Lebenszyklus-Ereignisses.
curl -sS -X PATCH "$BATTERYPASS_URL/api/v1/batteries/0192a3f0-5b7c-7d21-8e4f-6a2b9c1d3e5f/condition" \
  -H "Authorization: Bearer $BATTERYPASS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "measured_at": "2026-10-24T06:00:00Z",
    "note": "BMS daily report",
    "values": [
      { "field_key": "condition.state_of_charge", "value": 81.5 },
      { "field_key": "condition.number_of_full_cycles", "value": 412 },
      { "field_key": "condition.remaining_capacity", "value": 187.2, "measured_at": "2026-10-24T05:40:00Z" }
    ]
  }'
200 (gekürzt)
{
  "accepted": [
    {
      "field_key": "condition.state_of_charge",
      "value": 81.5,
      "unit": "%",
      "revision": 9,
      "source": "api",
      "review_status": "approved",
      "measured_at": "2026-10-24T06:00:00Z",
      "recorded_at": "2026-10-24T06:00:03Z",
      "reviewed_at": "2026-10-24T06:00:03Z",
      "registry_version": "0.5.0",
      "checks": []
    },
    {
      "field_key": "condition.remaining_capacity",
      "value": 187.2,
      "unit": "Ah",
      "revision": 5,
      "source": "api",
      "review_status": "approved",
      "measured_at": "2026-10-24T05:40:00Z",
      "recorded_at": "2026-10-24T06:00:03Z",
      "reviewed_at": "2026-10-24T06:00:03Z",
      "registry_version": "0.5.0",
      "checks": []
    }
  ],
  "skipped": [
    { "field_key": "condition.number_of_full_cycles", "reason": "unchanged" }
  ],
  "event": {
    "id": "0192f8b1-2a3c-7d4e-9f50-61a2b3c4d5e6",
    "battery_id": "0192a3f0-5b7c-7d21-8e4f-6a2b9c1d3e5f",
    "type": "condition_update",
    "occurred_on": "2026-10-24",
    "description": "BMS daily report",
    "source": "api",
    "api_key": { "id": "0192e4c7-8b9a-7c6d-8e5f-4a3b2c1d0e9f", "name": "BMS Landshut" },
    "field_keys": ["condition.state_of_charge", "condition.remaining_capacity"],
    "evidence": [],
    "created_at": "2026-10-24T06:00:03Z"
  },
  "publication": {
    "outcome": "published",
    "version": {
      "version_no": 4,
      "published_at": "2026-10-24T06:00:03Z",
      "reason": "condition update",
      "registry_version": "0.5.0",
      "canonical_hash": "sha256:5d0c9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d",
      "public_hash": "sha256:7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d5d0c9e8f7a6b5c4d3e2f1a0b9c8d",
      "key_id": "2026-10-k1",
      "batterypass_v2_valid": true,
      "batterypass_v2_issue_count": 0
    }
  }
}

Das Ergebnis lesen

accepted enthält die gespeicherten Werte mit source: api, review_status: approved und ihrem measured_at. skipped nennt Werte, die gültig waren, aber nicht gespeichert wurden:

reasonBedeutung
older_measurementDer gespeicherte Wert wurde später gemessen als der gesendete.
unchangedDer gespeicherte Wert hat denselben Wert und denselben Messzeitpunkt, oder Sie haben ein Feld ohne Wert geleert.

event ist das Ereignis condition_update im Lebenszyklus der Einheit; es fehlt, wenn nichts übernommen wurde. Sein occurred_on ist der UTC-Tag der jüngsten übernommenen Messung, und note wird seine description.

publication.outcome sagt, was mit dem Pass geschah:

outcomeBedeutung
publishedEine neue Passversion mit dem Grund condition update ist jetzt online (version).
unchangedSofort veröffentlicht, aber der öffentliche Inhalt hat sich nicht geändert; es entstand keine neue Version.
scheduledIhre Organisation veröffentlicht täglich: Der Lauf um 02:00 UTC übernimmt die neuen Werte.
blockedDie Veröffentlichungsprüfung hat abgelehnt (blockers). Die Werte sind gespeichert; der Pass bleibt im Status update_needed online, bis ein Mitglied ihn erneut veröffentlicht.
not_publishedDie Einheit hat keinen öffentlichen Pass; die Werte erscheinen mit der ersten Veröffentlichung.

Die Regel (immediate oder daily) ist eine Einstellung der Organisation im Portal; getCondition zeigt sie als republish. Die meisten Zustandsfelder gehören zur Zugriffsstufe legitimate_interest: Sie stehen im signierten Snapshot und in den eingeschränkten Ansichten, während das öffentliche JSON nur ihre Schlüssel in restricted_fields_present nennt (siehe Zugriffsstufen).

Regeln für ein Update

  • Merge. Nur die genannten Felder ändern sich; alle anderen behalten ihren Wert. null leert ein Feld.
  • Messzeitpunkt. Jeder Wert braucht ein measured_at, ein eigenes oder das der Anfrage. Es darf höchstens fünf Minuten nach der Serveruhr liegen und nicht vor dem Herstellungsdatum der Einheit. Senden Sie es in UTC (Z).
  • Die jüngste Messung gewinnt. Ein Wert, der früher gemessen wurde als der gespeicherte, wird übersprungen; verspätete oder doppelte Lieferungen richten also keinen Schaden an. Dasselbe Update zweimal zu senden ist unbedenklich: Beim zweiten Mal kommt alles als unchanged zurück.
  • Alles oder nichts. Ist ein Wert ungültig oder verletzen die zusammengeführten Zustandsdaten eine feldübergreifende Prüfung des Registers, wird das ganze Update abgelehnt und nichts gespeichert.
  • Werte, keine Dokumente. updateCondition nimmt keine evidence_ids; einen Diagnosebericht hängen Sie an ein Lebenszyklus-Ereignis.

Fehler

400
{
  "type": "about:blank",
  "title": "Bad Request",
  "status": 400,
  "code": "validation_error",
  "detail": "The request failed validation.",
  "request_id": "4f9c2a7d1e0b5c8a3f6e2d19",
  "errors": [
    { "field": "values[0].field_key", "code": "unknown_field", "message": "performance.nominal_voltage is not condition data of this unit" },
    { "field": "values[1].measured_at", "code": "out_of_range", "message": "measured_at lies in the future" }
  ]
}
Status und codeTypische UrsacheWas zu tun ist
400 validation_errorvalues[i].field_key mit unknown_field (kein dynamisches Feld dieser Einheit); values[i].measured_at mit required oder out_of_range; values[i].value außerhalb des Wertebereichs; ein Feld doppelt; eine fehlgeschlagene feldübergreifende Prüfung; note zu langDaten korrigieren; nicht unverändert wiederholen
401 unauthenticatedSchlüssel fehlt, ist unbekannt oder widerrufenSchlüssel im Secret-Speicher prüfen
403 forbiddenDem Schlüssel fehlt der Scope conditionEinen Schlüssel mit diesem Scope erstellen lassen
404 not_foundDie Einheit gibt es in der Organisation des Schlüssels nichtID prüfen
409 conflictDas Batteriemodell der Einheit ist archiviert: Seine Daten lassen sich lesen, aber nicht ändernFür Einheiten dieses Modells nichts mehr melden
429 rate_limitedMehr als 600 Anfragen pro Minute über alle Schlüssel der OrganisationRetry-After abwarten, dann erneut senden

Fehler und Wiederholungen zeigt eine Hilfsfunktion für Wiederholungen; das Rezept Nächtlicher Zustandsdaten-Push sendet ein Update je Einheit mit Backoff.

Auf dieser Seite