API-Anforderungen für Telemetrie-Upload
Version: 2.0
Stand: 13.07.2026
Herausgeber: Dexa Solutions GmbH
Produkt: Safe Fire House (SFH)
1. Übersicht
Dieses Dokument beschreibt die REST-API-Anforderungen für die aktive Übermittlung (Push) der Telemetriedaten der Safe Fire House Brandwarnanlage an einen empfangenden REST-Endpoint. Die Zentrale ist hier der Client, das empfangende System der Server. Der übermittelte Datenbaum entspricht dem Response-Baum des Pull-Endpoints (Seite 241).
| Parameter | Wert |
|---|---|
| Method | POST |
| Content-Type | application/json |
| Accept | application/json |
| Frequenz | Konfigurierbarer Zeitplan (täglich / wöchentlich / monatlich), azyklisch bei Alarm — [zu bestätigen] |
| Rate Limit | Max. 60 Requests/Minute |
1.1 Authentifizierung
Eine der folgenden Methoden muss vom empfangenden System unterstützt werden:
| Methode | Header / Mechanismus | Beispiel |
|---|---|---|
| API-Key | X-API-Key |
X-API-Key: <key> |
| Bearer Token (JWT) | Authorization: Bearer |
Authorization: Bearer <token> |
| X.509 Client-Zertifikat | mTLS (Mutual TLS) | Client-Zertifikat im TLS-Handshake |
2. Payload-Struktur
Root
├── timestamp
├── fireStation
├── deviceId
└── objects[]
├── type (vehicle | room | hall)
├── vehicleId
├── licencePlate
├── callSign
├── vehicleType
└── smokeDetectors[]
├── name
├── address
├── type
└── ...
Wertetypen: Alle Schlüssel sind camelCase. Alle skalaren Werte werden als JSON-String ausgegeben (auch Zahlen und Flags, z. B. "rssiDevice": "-71", "battery": "false", "alarmState": "0"). objects und smokeDetectors sind echte JSON-Arrays.
Hinweis zu type: Das Feld type tritt auf zwei Ebenen auf — auf Objekt-Ebene als Träger-Art (vehicle|room|hall), auf SmokeDetector-Ebene als Melder-Typ (konstant "SFHSS02").
3. Root-Objekt
| Key | Description | Type | Constraints |
|---|---|---|---|
timestamp |
Zeitstempel der Erstellung | string |
ISO 8601 UTC (YYYY-MM-DDTHH:mm:ssZ) |
fireStation |
Wache (Name, Adresse) | string |
Max. 150 Zeichen |
deviceId |
Seriennummer der Zentrale | string |
14 Zeichen, hexadezimal |
objects |
Auflistung der Objekte (Fahrzeug/Raum/Halle) | array |
Array von Objekt-Einträgen (siehe Abschnitt 4) |
Beispiel:
{
"timestamp": "2026-07-13T11:24:13Z",
"fireStation": "Feuerwehr Feuerstadt, Hauptstr. 112, 01234 Feuerstadt",
"deviceId": "001A2B3C4D5E6F",
"objects": [ ... ]
}
4. Objekt-Eintrag
Ein Objekt-Eintrag bündelt die Rauchsensoren eines Trägers. Das Feld type unterscheidet die Träger-Art. Die fahrzeugspezifischen Felder (vehicleId, licencePlate, callSign, vehicleType) sind bei type = "vehicle" befüllt; für room/hall können sie leer bzw. "n.a." sein.
| Key | Description | Type | Constraints |
|---|---|---|---|
type |
Art des Trägers | string |
Enum: "vehicle" | "room" | "hall" (derzeit nur "vehicle" belegt) |
vehicleId |
Fahrzeug-Identifikationsnummer (VIN) | string |
17 Zeichen; "n.a." falls nicht hinterlegt (siehe 7.1) |
licencePlate |
Kennzeichen | string |
Max. 10 Zeichen; "n.a." falls nicht hinterlegt (siehe 7.1) |
callSign |
Funkrufname | string |
Max. 50 Zeichen |
vehicleType |
Fahrzeugtyp | string |
Max. 50 Zeichen; "n.a." falls nicht hinterlegt (siehe 7.1) |
smokeDetectors |
Auflistung der Rauchsensoren | array |
Array von SmokeDetector-Objekten; [] falls keine Melder zugeordnet (siehe 7.2) |
Beispiel:
{
"type": "vehicle",
"vehicleId": "WVWZZZ3CZWE123456",
"licencePlate": "FS-FW 112",
"callSign": "1-HLF20-1",
"vehicleType": "HLF20",
"smokeDetectors": [ ... ]
}
5. SmokeDetector-Objekt
Alle Werte sind Strings (siehe Hinweis in Abschnitt 2). Fehlt ein einzelner Datapoint, wird ein typ-konformer Default geliefert (nie null) — siehe Abschnitt 7.3.
| Key | Description | Type | Constraints |
|---|---|---|---|
name |
Rauchsensorbezeichnung | string |
Max. 30 Zeichen |
address |
Rauchsensoradresse | string |
14 Zeichen, hexadezimal |
type |
Rauchsensortyp | string |
Konstant "SFHSS02" |
version |
Hardware-Version | string |
numerisch, ≥ 1 |
group |
Gruppierung | string |
0–9 oder leer |
teams |
Reserviert | string |
i. d. R. leer |
firmware |
Firmware-Version | string |
Max. 9 Zeichen, Pattern [0-9.]+ |
rssiDevice |
Funkempfangswert Gerät (dBm) | string |
numerisch, −128 bis 128 |
rssiPeer |
Funkempfangswert Sender (dBm) | string |
numerisch, −128 bis 128 |
battery |
Flag: Batterieleistung niedrig | string |
"true" / "false" |
unreachState |
Flag: Gerät nicht erreichbar | string |
"true" / "false" |
unreachCumulative |
Kumulierte Nichterreichbarkeit (Tage) | string |
numerisch (0–9999) oder "n.a." (siehe 7.2) |
operationTime |
Betriebszeit (Tage) | string |
numerisch, 0–9999 |
dirtLevel |
Verschmutzungsgrad | string |
float-String (z. B. "0.000000") |
smokeLevel |
Raucherkennungsgrad | string |
float-String (z. B. "0.000000") |
alarmState |
Alarmstatus | string |
"0"–"3" (siehe Enum, Abschnitt 6.1) |
voltage |
Batteriespannung (V) | string |
float-String (0.0–3.2) |
chamber |
Flag: Rauchkammer verschmutzt | string |
"true" / "false" |
errorCode |
Fehlercode | string |
numerisch, 0–99 |
Beispiel:
{
"name": "1-HLF20-1 RM1",
"address": "00AABBCCDDEE11",
"type": "SFHSS02",
"version": "1",
"group": "",
"teams": "",
"firmware": "1.0.6",
"rssiDevice": "-65",
"rssiPeer": "0",
"battery": "false",
"unreachState": "false",
"unreachCumulative": "0",
"operationTime": "180",
"dirtLevel": "0.000000",
"smokeLevel": "0.000000",
"alarmState": "0",
"voltage": "3.000000",
"chamber": "false",
"errorCode": "0"
}
6. Enums & Flag-Logik
6.1 alarmState
| Wert | Bedeutung |
|---|---|
"0" |
Ruhezustand – Kein Rauch erkannt |
"1" |
Lokaler Alarm – Rauch erkannt |
"2" |
Reserviert |
"3" |
Broadcast-Alarm – Anderer Sensor in Funkreichweite hat Rauch erkannt |
6.2 Flag-Logik
| Flag | Bedeutung wenn "true" |
Zusatzinfo |
|---|---|---|
chamber |
Rauchkammer verschmutzt | Siehe dirtLevel |
battery |
Batterieleistung niedrig | Siehe voltage (V) |
unreachState |
Gerät nicht erreichbar | Siehe unreachCumulative (Tage) |
7. Sonderfälle & Defaults
7.1 Fahrzeug-Metadaten nicht deklariert
vehicleId, licencePlate und vehicleType werden je callSign aus der Fahrzeug-Stammdatenpflege der Zentrale gelesen:
| Situation | Ausgabe |
|---|---|
callSign fehlt in der Stammdatenpflege |
"n.a." |
| Eintrag vorhanden, Wert leer | "" (leerer String) |
| Eintrag + Wert vorhanden | der Wert |
callSign selbst stammt aus der Fahrzeugliste und ist immer gesetzt.
7.2 Gerät nicht erreichbar / nicht gepairt
| Fall | Verhalten |
|---|---|
| Melder gepairt, aber offline | erscheint im Baum; unreachState = "true"; unreachCumulative = Tage seit letztem Kontakt bzw. "n.a."; übrige Werte = zuletzt bekannter Stand |
| Melder nicht (mehr) gepairt | Melder fehlt im Array. Ein Fahrzeug ohne zugeordnete Melder liefert "smokeDetectors": [] |
7.3 Fehlender Datapoint → typ-konformer Default
| Feld(er) | Default |
|---|---|
battery, unreachState, chamber |
"false" |
rssiDevice, rssiPeer, errorCode, operationTime, alarmState |
"0" |
voltage, smokeLevel, dirtLevel |
"0.000000" |
firmware, group, version, teams |
"" |
unreachCumulative (keine Historie) |
"n.a." |
8. Response
8.1 Erwartete HTTP Status Codes (vom empfangenden System)
| Code | Bedeutung |
|---|---|
200 OK / 201 Created |
Erfolgreich verarbeitet |
400 Bad Request |
Ungültiger Payload |
401 Unauthorized |
Fehlende oder ungültige Authentifizierung |
403 Forbidden |
Keine Berechtigung |
429 Too Many Requests |
Rate Limit überschritten (Retry-After beachten) |
500 Internal Server Error |
Serverfehler |
503 Service Unavailable |
Service nicht verfügbar |
8.2 Success Response
{
"status": "ok",
"received": "2026-07-13T11:24:13Z"
}
8.3 Error Response
{
"error": "invalid_payload",
"message": "Field 'address' invalid"
}
9. Retry & Idempotenz (Zentrale-seitig)
| Fehlertyp | Retry | Wartezeit |
|---|---|---|
| Netzwerkfehler | ja | 5 s, 10 s, 30 s |
| HTTP 5xx | ja | 5 s, 10 s, 30 s |
| HTTP 429 | ja | Retry-After-Header beachten |
| HTTP 4xx (außer 429) | nein | – |
Wiederholte Übermittlungen desselben Snapshots sind unkritisch (Telemetrie ist ein Zustands-Snapshot, kein Ereignis-Insert). Ein optionales Idempotenz-Merkmal kann über timestamp + deviceId gebildet werden.
10. Sicherheit
| Anforderung | Beschreibung |
|---|---|
| Transport | ausschließlich HTTPS (TLS 1.2+) |
| Zugangsdaten | verschlüsselt auf der Zentrale; Werte im dexa-Credstore, nie im Klartext in Doku/Skripten |
| Token-Rotation | nach Vorgabe des empfangenden Systems |
11. Vollständiges Payload-Beispiel
{
"timestamp": "2026-07-13T11:24:13Z",
"fireStation": "Feuerwehr Feuerstadt, Hauptstr. 112, 01234 Feuerstadt",
"deviceId": "001A2B3C4D5E6F",
"objects": [
{
"type": "vehicle",
"vehicleId": "WVWZZZ3CZWE123456",
"licencePlate": "FS-FW 112",
"callSign": "1-HLF20-1",
"vehicleType": "HLF20",
"smokeDetectors": [
{
"name": "1-HLF20-1 RM1",
"address": "00AABBCCDDEE11",
"type": "SFHSS02",
"version": "1",
"group": "",
"teams": "",
"firmware": "1.0.6",
"rssiDevice": "-65",
"rssiPeer": "0",
"battery": "false",
"unreachState": "false",
"unreachCumulative": "0",
"operationTime": "180",
"dirtLevel": "0.000000",
"smokeLevel": "0.000000",
"alarmState": "0",
"voltage": "3.000000",
"chamber": "false",
"errorCode": "0"
},
{
"name": "1-HLF20-1 RM2",
"address": "00AABBCCDDEE22",
"type": "SFHSS02",
"version": "1",
"group": "",
"teams": "",
"firmware": "1.0.6",
"rssiDevice": "-72",
"rssiPeer": "0",
"battery": "false",
"unreachState": "false",
"unreachCumulative": "0",
"operationTime": "180",
"dirtLevel": "0.000000",
"smokeLevel": "0.000000",
"alarmState": "0",
"voltage": "3.000000",
"chamber": "false",
"errorCode": "0"
}
]
}
]
}