Direkt zum Hauptinhalt

API-Anforderungen für Telemetrie-Abruf (GET)

Version: 1.45
Stand: Juni 2026
Herausgeber: Dexa Solutions GmbH
Produkt: Safe Fire House (SFH)


1. Übersicht

Dieses Dokument beschreibt den REST-API-Endpoint, über den ein externes System die aktuellen Telemetriedaten der Safe Fire House Brandwarnanlage aktiv abruft (Pull). Die Zentrale ist hier der Server, das abrufende System der Client. Die Antwort enthält den Datenbaum aus Wache, Fahrzeugen und Rauchsensoren.

Parameter Wert
Method GET
Pfad /api/health (mit oder ohne abschließenden /)
Accept application/json
Response-Type application/json; charset=utf-8
Frequenz On-Demand (Client-gesteuert)
Rate Limit 5 Requests/Sekunde pro Client-IP, Burst 10 (sonst 429)
Caching Antwort bis zu 20 s serverseitig gecacht (siehe Abschnitt 9)

1.1 Authentifizierung

Der Endpoint erfordert ein Bearer-Token im Authorization-Header. Das Token wird je Zentrale vergeben und vertraulich an das abrufende System übergeben.

Methode Header / Mechanismus Beispiel
Bearer Token Authorization: Bearer Authorization: Bearer bffdc50d5a1173159...

Fehlt der Header oder ist das Token ungültig, antwortet der Endpoint mit 401. Ist serverseitig kein Token konfiguriert, antwortet er mit 503 (fail-closed, keine Datenausgabe).


2. Endpoint

GET http(s)://<zentrale-host>/api/health
  • <zentrale-host> = IP oder Hostname der Zentrale im lokalen Netz (z. B. 192.168.1.16).
  • Erreichbar über den Reverse-Proxy der Zentrale; der Authorization-Header wird unverändert durchgereicht.
  • Der abschließende Slash ist optional (/api/health und /api/health/ sind gleichwertig).

3. Request

Es wird kein Request-Body gesendet. Erforderlicher Header:

Header Pflicht Wert
Authorization ja Bearer <token>

Beispiel:

curl --location 'http://192.168.1.16/189.165/api/health/' \
  --header 'Authorization: Bearer <token>'

4. Payload-Struktur (Response)

Root
├── timestamp
├── fireStation
├── deviceId
└── objects[]
    ├── type            (vehicle | room | hall)
    ├── vehicleId
    ├── sign
    ├── callSign
    ├── vehicleType
    └── smokeDetectors[]
        ├── name
        ├── address
        ├── type
        └── ...

Hinweis zu 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.


5. 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 6)

Beispiel:

{
  "timestamp": "2026-06-09T11:24:13Z",
  "fireStation": "Feuerwehr Feuerstadt, Hauptstr. 112, 01234 Feuerstadt",
  "deviceId": "001A2B3C4D5E6F",
  "objects": [ ... ]
}

6. Vehicle-ObjektObjekt-Eintrag

Ein Objekt-Eintrag bündelt die Rauchsensoren eines Trägers. Das Feld type unterscheidet die Träger-Art. Die fahrzeugspezifischen Felder (vehicleId, sign, callSign, vehicleType) sind bei type = "vehicle" befüllt; für room/hall können sie leer bzw. "n.a." sein.

Key Description Type Constraints
typeArt des TrägersstringEnum: "vehicle" | "room" | "hall" (derzeit nur "vehicle" belegt)
vehicleId Fahrzeug-Identifikationsnummer (VIN) string 17 Zeichen; "n.a." falls nicht hinterlegt (siehe 8.1)
sign Kennzeichen string Max. 10 Zeichen; "n.a." falls nicht hinterlegt (siehe 8.1)
callSign Funkrufname string Max. 50 Zeichen
vehicleType Fahrzeugtyp string Max. 50 Zeichen; "n.a." falls nicht hinterlegt (siehe 8.1)
smokeDetectors Auflistung der Rauchsensoren array Array von SmokeDetector-Objekten; [] falls keine Melder zugeordnet (siehe 8.2)

Beispiel:

{
  "type": "vehicle",
  "vehicleId": "WVWZZZ3CZWE123456",
  "sign": "FS-FW 112",
  "callSign": "1-HLF20-1",
  "vehicleType": "HLF20",
  "smokeDetectors": [ ... ]
}

7. SmokeDetector-Objekt

Alle Werte sind Strings (siehe Hinweis in Abschnitt 4). Fehlt ein einzelner Datapoint, wird ein typ-konformer Default geliefert (nie null) — siehe Abschnitt 8.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 09 oder leer
teams Reserviert string i. d. R. leer (siehe Abschnitt 11)
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 8.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 7.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"
}

7.1 Enum: 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

7.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)

8. Sonderfälle & Defaults

8.1 Fahrzeug-Metadaten nicht deklariert

vehicleId, sign und vehicleType werden je callSign aus der Fahrzeug-Stammdatenpflege der Zentrale gelesen. Verhalten pro Feld (einzeln):

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.

8.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 (kein Live-Funk-Poll beim Abruf)
Melder nicht (mehr) gepairt Melder fehlt im Array. Ein Fahrzeug ohne zugeordnete Melder liefert "smokeDetectors": []

unreachCumulative = "n.a." bedeutet „nicht in der Erreichbarkeits-Historie der Zentrale geführt", nicht zwingend „erreichbar".

8.3 Fehlender Datapoint → typ-konformer Default

Existiert ein einzelner Sensor-Datapoint nicht (abweichendes Geräteprofil o. Ä.), wird statt null ein Default ausgegeben:

Feld(er) Default
battery, unreachState, chamber "false"
rssiDevice, rssiPeer, errorCode, operationTime, alarmState "0"
voltage, smokeLevel, dirtLevel "0.000000"
firmware, group, version, teams (keine Geräte-Metadaten) ""
unreachCumulative (keine Historie) "n.a."

9. Caching & Nebenläufigkeit

  • TTL-Cache: Die Antwort wird serverseitig bis zu 20 s zwischengespeichert. Aufeinanderfolgende Abrufe innerhalb dieses Fensters liefern denselben (bis zu 20 s alten) Stand, ohne die Zentrale erneut abzufragen.
  • Single-Flight: Pro Cache-Miss läuft höchstens eine Datenerhebung. Treffen mehrere Abrufe gleichzeitig ein, teilen sie sich das laufende Ergebnis; es werden keine parallelen Erhebungen gestartet.
  • Die Werte spiegeln den zuletzt in der Zentrale bekannten Zustand der Sensoren wider (kein aktiver Funk-Poll der Geräte beim Abruf).

10. Response (HTTP)

10.1 Status Codes

Code Bedeutung
200 OK Telemetrie erfolgreich geliefert (Body = Datenbaum)
401 Unauthorized Fehlender oder ungültiger Authorization-Header
429 Too Many Requests Rate Limit überschritten
502 Bad Gateway Telemetrie nicht lesbar (Zentrale nicht erreichbar)
503 Service Unavailable Serverseitig kein API-Token konfiguriert

10.2 Success Response

Body ist der vollständige Telemetrie-Datenbaum (siehe Abschnitt 12)11).

10.3 Error Response

{
  "error": "unauthorized"
}
{
  "error": "telemetryUnavailable",
  "detail": "telemetry source returned HTTP 500"
}
error HTTP Bedeutung
unauthorized 401 Token fehlt/falsch
telemetryUnavailable 502 Datenerhebung fehlgeschlagen (detail)
apiTokenNotConfigured 503 Kein Token gesetzt

11. Verhältnis zum Telemetrie-Upload

Dieser Endpoint ist eigenständig; das zyklische Telemetrie-Upload diente nur als fachliche Vorlage. Die Schlüssel sind durchgängig camelCase. Verbleibende Unterschiede zum Dokument „API-Anforderungen für Telemetrie-Upload":

AspektUpload-DokumentDieser Endpoint (Abruf)
Wurzel-Arrayvehiclesobjects (enthält auch Räume/Hallen, nicht nur Fahrzeuge)
Detector-Keys (mehrwortig)lowercase (operationtime, dirtlevel, smokelevel, alarmstate, errorcode)camelCase (operationTime, dirtLevel, smokeLevel, alarmState, errorCode)
Wertetypentypisiert (integer/float/boolean/array)alle skalaren Werte als String
teamsarray ([])string (i. d. R. leer)

Beide Schemata können unabhängig weiterentwickelt werden.


12. Vollständiges Response-Beispiel

{
  "timestamp": "2026-06-09T11:24:13Z",
  "fireStation": "Feuerwehr Feuerstadt, Hauptstr. 112, 01234 Feuerstadt",
  "deviceId": "001A2B3C4D5E6F",
  "objects": [
    {
      "type": "vehicle",
      "vehicleId": "WVWZZZ3CZWE123456",
      "sign": "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"
        }
      ]
    }
  ]
}