Spezifikationen Technische Spezifikationen und API-Anforderungen zum Safe Fire House API Schnittstellenspezifikation API-Anforderungen für Alarmierungen Version: 1.2 Stand: 2026-03 Herausgeber: Dexa Solutions GmbH Produkt: Safe Fire House (SFH) 1. Übersicht Diese Spezifikation definiert die REST-API-Schnittstelle für die Übermittlung von Alarmdaten von der Safe Fire House Brandwarnanlage an externe Alarmierungsdienste. Die API ermöglicht sowohl die Erstmeldung eines Alarms als auch nachfolgende Updates bei Broadcast-Alarmen. 1.1 Alarmtypen Typ Beschreibung Methode ALARM Lokaler Rauchalarm – Einzelner Rauchsensor hat ausgelöst POST ALARM (Broadcast) Folge-Alarm – Weitere Rauchsensoren in Funkreichweite PUT TEST Schnittstellen-Test zur Validierung der Verbindung POST 2. API-Parameter Parameter Wert Base-URL https://{partner-domain}/api/v1 Content-Type application/json; charset=UTF-8 Accept application/json Zeichenkodierung UTF-8 2.1 Authentifizierung Die Authentifizierung erfolgt via Bearer Token im HTTP-Header: Authorization: Bearer {access_token} Parameter Beschreibung access_token Vom Partner bereitgestellter API-Schlüssel (min. 32 Zeichen) Hinweis: Der Token wird pro Kunde/Standort vom Partner generiert und im SFH-System hinterlegt. 2.2 Rate Limiting Parameter Wert Max. Requests 60 pro Minute Retry-After Bei HTTP 429 im Header angegeben 3. Erstalarm (POST) Sendet einen neuen Alarm an das Partner-System. Der Partner legt einen neuen Alarm-Datensatz an und gibt eine eindeutige alarmId zurück. 3.1 Request POST /api/v1/alarms HTTP/1.1 Host: {partner-domain} Authorization: Bearer {access_token} Content-Type: application/json Accept: application/json 3.2 Request-Body { "externalCreatedAt": "2026-03-13T15:30:00Z", "externalId": "SFH-20260313-153000-001", "keyword": "ALARM", "keywordAddition": "RAUCHSENSOR-ALARM", "info": "Rauchsensor hat durch lokale Raucherkennung ausgelöst!", "priority": false, "send_push": true, "send_sms": false, "send_call": false, "group": "FW-Musterstadt-Zug1", "destination": { "objectName": "Feuerwehrgerätehaus Musterstadt", "info": "Fahrzeughalle", "street": "Hauptstraße", "houseNumber": "112", "zipCode": "12345", "city": "Musterstadt", "coordinates": { "latitude": 51.123456, "longitude": 7.654321 }, "fireAlarmSystem": "Safe Fire House" }, "publisherInfos": { "systemName": "DXO-SFH-CU-X-02", "version": "2.0" }, "reporter": [ { "name": "HLF20-Kabine", "info": "Raucherkennung" } ] } 3.3 Request-Felder Root-Objekt Feld Typ Pflicht Beschreibung externalCreatedAt string ✓ Zeitstempel der Alarmerstellung (ISO 8601, UTC) externalId string ✓ Eindeutige Alarm-ID aus dem SFH-System (für Idempotenz) keyword string ✓ Alarmtyp: ALARM oder TEST keywordAddition string ✓ Detailbeschreibung: RAUCHSENSOR-ALARM , SCHNITTSTELLEN-TEST info string ✓ Freitext-Information zum Alarm priority boolean ✓ Prioritäts-Flag (reserviert für zukünftige Nutzung) send_push boolean ✓ Push-Benachrichtigung senden send_sms boolean ✓ SMS-Benachrichtigung senden send_call boolean ✓ Telefonanruf auslösen group string ✓ Alarmierungsgruppe/RIC beim Partner destination object ✓ Standort-Objekt (siehe unten) publisherInfos object ✓ System-Informationen (siehe unten) reporter array ✓ Array von Rauchsensor-Objekten (siehe unten) destination-Objekt Feld Typ Pflicht Beschreibung objectName string ✓ Name des Gebäudes/Objekts info string Zusatzinformation zum Standort street string ✓ Straßenname houseNumber string ✓ Hausnummer zipCode string ✓ Postleitzahl city string ✓ Stadt/Ort coordinates object ✓ Koordinaten-Objekt mit latitude und longitude fireAlarmSystem string ✓ Systemkennung, immer Safe Fire House coordinates-Objekt Feld Typ Pflicht Beschreibung latitude number ✓ Breitengrad (WGS84, Dezimalgrad) longitude number ✓ Längengrad (WGS84, Dezimalgrad) publisherInfos-Objekt Feld Typ Pflicht Beschreibung systemName string ✓ Produktkennung, beispielsweise DXO-SFH-CU-X-02 version string ✓ Produktversion: 1.0 oder 2.0 reporter-Objekt (Array-Element) Feld Typ Pflicht Beschreibung name string ✓ Gerätename/OPTA des auslösenden Rauchsensors info string ✓ Art der Erkennung, beispielsweise Raucherkennung 3.4 Response (Erfolg) HTTP/1.1 201 Created Content-Type: application/json { "status": "created", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "received": "2026-03-13T15:30:01Z" } Feld Typ Beschreibung status string created bei erfolgreichem Anlegen alarmId string Eindeutige ID des angelegten Alarms (UUID oder PK) – wird für PUT benötigt! received string Zeitstempel der Verarbeitung beim Partner (ISO 8601, UTC) 4. Alarm-Update (PUT) Aktualisiert einen bestehenden Alarm (beispielsweise bei Broadcast-Alarm, wenn weitere Rauchsensoren auslösen). Die alarmId aus der POST-Response wird im URL-Pfad übergeben. 4.1 Request PUT /api/v1/alarms/{alarmId} HTTP/1.1 Host: {partner-domain} Authorization: Bearer {access_token} Content-Type: application/json Accept: application/json URL-Parameter: Parameter Beschreibung alarmId Die vom Partner beim POST zurückgegebene Alarm-ID 4.2 Request-Body { "alarmId": "550e8400-e29b-41d4-a716-446655440000", "externalId": "SFH-20260313-153000-001", "externalUpdatedAt": "2026-03-13T15:30:10Z", "keyword": "ALARM", "keywordAddition": "RAUCHSENSOR-ALARM (BROADCAST)", "info": "Weitere Rauchsensoren haben durch Broadcast-Alarm ausgelöst!", "priority": false, "send_push": true, "send_sms": false, "send_call": false, "group": "FW-Musterstadt-Zug1", "destination": { "objectName": "Feuerwehrgerätehaus Musterstadt", "info": "Fahrzeughalle", "street": "Hauptstraße", "houseNumber": "112", "zipCode": "12345", "city": "Musterstadt", "coordinates": { "latitude": 51.123456, "longitude": 7.654321 }, "fireAlarmSystem": "Safe Fire House" }, "publisherInfos": { "systemName": "DXO-SFH-CU-X-02", "version": "2.0" }, "reporter": [ { "name": "HLF20-Kabine", "info": "Raucherkennung" }, { "name": "HLF20-Mannschaftsraum", "info": "Raucherkennung (Broadcast)" } ] } 4.3 Unterschiede zum POST Feld POST PUT alarmId Nicht vorhanden ✓ Pflicht (im Body UND URL) externalCreatedAt ✓ Nicht vorhanden externalUpdatedAt Nicht vorhanden ✓ Pflicht keywordAddition RAUCHSENSOR-ALARM RAUCHSENSOR-ALARM (BROADCAST) reporter 1 Rauchsensor 1+ Rauchsensoren (kumulativ) 4.4 Response (Erfolg) HTTP/1.1 200 OK Content-Type: application/json { "status": "updated", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "received": "2026-03-13T15:30:11Z" } 5. Alarm-Status abrufen (GET) Ruft den aktuellen Status eines Alarms ab, einschließlich der Rückmeldungen der alarmierten Einsatzkräfte. 5.1 Request GET /api/v1/alarms/{alarmId} HTTP/1.1 Host: {partner-domain} Authorization: Bearer {access_token} Accept: application/json URL-Parameter: Parameter Beschreibung alarmId Die vom Partner beim POST zurückgegebene Alarm-ID 5.2 Response (Erfolg) HTTP/1.1 200 OK Content-Type: application/json { "status": "ok", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "externalId": "SFH-20260313-153000-001", "alarmStatus": "active", "createdAt": "2026-03-13T15:30:01Z", "updatedAt": "2026-03-13T15:30:11Z", "feedback": { "total": 12, "responses": [ { "type": "coming", "label": "Komme", "count": 7 }, { "type": "coming_delayed", "label": "Komme später", "count": 2, "details": [ { "eta": 5, "count": 1 }, { "eta": 10, "count": 1 } ] }, { "type": "not_available", "label": "Nicht verfügbar", "count": 3 } ], "pending": 5 }, "received": "2026-03-13T15:31:00Z" } 5.3 Response-Felder Root-Objekt Feld Typ Beschreibung status string ok bei erfolgreicher Abfrage alarmId string Partner-interne Alarm-ID (UUID/PK) externalId string Ursprüngliche ID aus dem SFH-System (für Abgleich) alarmStatus string Aktueller Alarmstatus (siehe Enum) createdAt string Zeitpunkt der Alarmerstellung beim Partner (ISO 8601) updatedAt string Zeitpunkt der letzten Aktualisierung (ISO 8601) feedback object Rückmeldungs-Objekt (siehe unten) received string Zeitstempel dieser Abfrage (ISO 8601) alarmStatus Enum Wert Beschreibung active Alarm ist aktiv, Alarmierung läuft acknowledged Alarm wurde quittiert closed Alarm wurde abgeschlossen cancelled Alarm wurde storniert feedback-Objekt Feld Typ Beschreibung total integer Gesamtzahl der alarmierten Einsatzkräfte responses array Array von Rückmelde-Objekten (siehe unten) pending integer Anzahl noch ausstehender Rückmeldungen responses-Objekt (Array-Element) Feld Typ Pflicht Beschreibung type string ✓ Maschinenlesbarer Rückmeldetyp (siehe Enum) label string ✓ Menschenlesbarer Text (Sprache des Partners) count integer ✓ Anzahl der Rückmeldungen dieses Typs details array Optional: Detailierte Aufschlüsselung (beispielsweise ETA-Zeiten) response.type Enum (Standardisiert) Typ Beschreibung coming Kommt zum Einsatz coming_delayed Kommt später (mit ETA) not_available Nicht verfügbar / Kommt nicht standby Bereitschaft / Evtl. verfügbar on_scene Bereits vor Ort unknown Sonstiger/Unbekannter Status details-Objekt (Optional, für coming_delayed) Feld Typ Beschreibung eta integer Geschätzte Ankunftszeit in Minuten count integer Anzahl mit dieser ETA 5.4 Beispiel: Status-Abfrage curl -X GET "https://partner.example.com/api/v1/alarms/550e8400-e29b-41d4-a716-446655440000" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \ -H "Accept: application/json" Response: { "status": "ok", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "externalId": "SFH-20260313-153000-001", "alarmStatus": "active", "createdAt": "2026-03-13T15:30:01Z", "updatedAt": "2026-03-13T15:30:11Z", "feedback": { "total": 12, "responses": [ { "type": "coming", "label": "Komme", "count": 7 }, { "type": "coming_delayed", "label": "Komme später", "count": 2, "details": [{ "eta": 5, "count": 1 }, { "eta": 10, "count": 1 }] }, { "type": "not_available", "label": "Nicht verfügbar", "count": 3 } ], "pending": 5 }, "received": "2026-03-13T15:31:00Z" } 6. Fehlerbehandlung 6.1 HTTP-Statuscodes Code Bedeutung Beschreibung 200 OK Alarm erfolgreich aktualisiert (PUT) 201 Created Alarm erfolgreich angelegt (POST) 400 Bad Request Ungültiger Request-Body oder fehlende Pflichtfelder 401 Unauthorized Fehlender oder ungültiger Bearer Token 403 Forbidden Token gültig, aber keine Berechtigung für diese Ressource 404 Not Found Alarm-ID nicht gefunden (bei PUT) 409 Conflict Alarm mit dieser externalId existiert bereits (bei POST) 429 Too Many Requests Rate Limit überschritten 500 Internal Server Error Serverfehler beim Partner 503 Service Unavailable Partner-System temporär nicht verfügbar 6.2 Fehler-Response { "status": "error", "error": "invalid_payload", "message": "Field 'externalId' is required", "received": "2026-03-13T15:30:01Z" } Feld Typ Beschreibung status string Immer error error string Fehlercode (siehe unten) message string Menschenlesbare Fehlerbeschreibung received string Zeitstempel der Fehlerverarbeitung 6.3 Fehlercodes Code Beschreibung invalid_payload JSON-Syntax ungültig oder Pflichtfeld fehlt invalid_field Feldwert entspricht nicht dem erwarteten Format unauthorized Token fehlt oder ist ungültig forbidden Keine Berechtigung für diese Operation not_found Ressource (Alarm) nicht gefunden duplicate Alarm mit dieser externalId existiert bereits rate_limited Zu viele Anfragen internal_error Interner Serverfehler 7. Idempotenz & Retry-Verhalten 7.1 Idempotenz Das Feld externalId dient der Idempotenz-Sicherung: Bei wiederholtem POST mit gleicher externalId sollte der Partner HTTP 409 Conflict zurückgeben Alternativ kann der Partner ein Upsert-Verhalten implementieren (Update statt Insert) 7.2 Retry-Strategie (SFH-seitig) Fehlertyp Retry Wartezeit Netzwerkfehler Ja 5s, 10s, 30s HTTP 5xx Ja 5s, 10s, 30s HTTP 429 Ja Retry-After Header beachten HTTP 4xx (außer 429) Nein – 8. Sicherheitsanforderungen Anforderung Beschreibung Transport Ausschließlich HTTPS (TLS 1.2+) Token-Speicherung Access Token verschlüsselt auf der SFH-Zentrale Token-Rotation Empfohlen: Jährliche Erneuerung IP-Whitelisting Optional: Partner kann SFH-IPs whitelisten 9. Beispiel: Vollständiger Alarm-Flow 9.1 Schritt 1: Lokaler Alarm (POST) Ein Rauchsensor im HLF20 löst aus: curl -X POST "https://partner.example.com/api/v1/alarms" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \ -H "Content-Type: application/json" \ -d '{ "externalCreatedAt": "2026-03-13T15:30:00Z", "externalId": "SFH-20260313-153000-001", "keyword": "ALARM", "keywordAddition": "RAUCHSENSOR-ALARM", "info": "Rauchsensor hat durch lokale Raucherkennung ausgelöst!", "priority": false, "send_push": true, "send_sms": false, "send_call": false, "group": "FW-Musterstadt-Zug1", "destination": { "objectName": "Feuerwehrgerätehaus Musterstadt", "info": "Fahrzeughalle", "street": "Hauptstraße", "houseNumber": "112", "zipCode": "12345", "city": "Musterstadt", "coordinates": { "latitude": 51.123456, "longitude": 7.654321 }, "fireAlarmSystem": "Safe Fire House" }, "publisherInfos": { "systemName": "DXO-SFH-CU-X-02", "version": "2.0" }, "reporter": [{ "name": "HLF20-Kabine", "info": "Raucherkennung" }] }' Response: { "status": "created", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "received": "2026-03-13T15:30:01Z" } 9.2 Schritt 2: Broadcast-Alarm (PUT) ~10 Sekunden später lösen weitere Rauchsensoren im Fahrzeug aus: curl -X PUT "https://partner.example.com/api/v1/alarms/550e8400-e29b-41d4-a716-446655440000" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \ -H "Content-Type: application/json" \ -d '{ "alarmId": "550e8400-e29b-41d4-a716-446655440000", "externalId": "SFH-20260313-153000-001", "externalUpdatedAt": "2026-03-13T15:30:10Z", "keyword": "ALARM", "keywordAddition": "RAUCHSENSOR-ALARM (BROADCAST)", "info": "Weitere Rauchsensoren haben durch Broadcast-Alarm ausgelöst!", "priority": false, "send_push": true, "send_sms": false, "send_call": false, "group": "FW-Musterstadt-Zug1", "destination": { "objectName": "Feuerwehrgerätehaus Musterstadt", "info": "Fahrzeughalle", "street": "Hauptstraße", "houseNumber": "112", "zipCode": "12345", "city": "Musterstadt", "coordinates": { "latitude": 51.123456, "longitude": 7.654321 }, "fireAlarmSystem": "Safe Fire House" }, "publisherInfos": { "systemName": "DXO-SFH-CU-X-02", "version": "2.0" }, "reporter": [ { "name": "HLF20-Kabine", "info": "Raucherkennung" }, { "name": "HLF20-Mannschaftsraum", "info": "Raucherkennung (Broadcast)" } ] }' Response: { "status": "updated", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "received": "2026-03-13T15:30:11Z" } Anhang A: Constraints Feld Constraint externalId Max. 50 Zeichen, Pattern: [A-Za-z0-9\-]+ keyword Enum: ALARM , TEST keywordAddition Max. 50 Zeichen info Max. 500 Zeichen group Max. 100 Zeichen destination.street Max. 100 Zeichen destination.houseNumber Max. 10 Zeichen destination.zipCode 5 Zeichen (DE) destination.city Max. 100 Zeichen coordinates.latitude -90.0 bis 90.0 coordinates.longitude -180.0 bis 180.0 reporter[].name Max. 50 Zeichen reporter Array Min. 1 Element API-Anforderungen für Gebäudezustandsmeldungen Version: 1.0 Stand: 2026-10 Herausgeber: Dexa Solutions GmbH Produkt: Safe Fire House (SFH) – Einbruchwarnsystem (EWS) 1. Übersicht Diese Spezifikation beschreibt die REST-Schnittstelle, über die ein Drittsystem – zum Beispiel eine Zutrittskontrollanlage, eine Gebäudeleittechnik oder eine Hausautomation – dem Einbruchwarnsystem der Safe-Fire-House-Zentrale den Gebäudezustand meldet und den Zustand der Anlage abfragt. Die Schnittstelle ersetzt den potentialfreien Kontakt eines Schlüsselschalters: Statt einen Draht zu schalten, teilt das Drittsystem der Zentrale über das Netzwerk mit, ob das Gebäude zugeschlossen oder aufgeschlossen ist. 1.1 Grundprinzip: Zustand statt Befehl Das Drittsystem meldet ausschließlich einen Zustand , keinen Schaltbefehl. Ob daraus ein Scharf- oder Unscharfschalten folgt, entscheidet das Regelwerk der Zentrale – nach denselben Regeln wie beim Schlüsselschalter (Abschnitt 6). Ein fehlerhaftes oder kompromittiertes Drittsystem kann dadurch höchstens einen falschen Gebäudezustand behaupten. Die Schutzregeln der Anlage – aktiver Alarm, Wartung, Störung – bleiben immer davor. 1.2 Funktionen Funktion Methode Pfad Recht Zustand der Anlage abfragen GET /api/intrusion/access/state Lesen Gebäudezustand melden POST /api/intrusion/access/report Schreiben 2. API-Parameter Parameter Wert Adresse https://{adresse-der-zentrale} – wird bei der Einrichtung mitgeteilt Content-Type application/json; charset=UTF-8 Accept application/json Zeichenkodierung UTF-8 Max. Größe einer Anfrage 4 KB Jede Zentrale hat eine Adresse, auch wenn sie mehrere Standorte überwacht. Welcher Standort gemeint ist, steht als Standort-Kennung in der Anfrage (Abschnitt 2.2). Die Schnittstelle ist in der Voreinstellung nur im internen Netz des Kunden erreichbar. Ein Zugang von außen wird nur auf ausdrücklichen Wunsch eingerichtet. 2.1 Authentifizierung Die Authentifizierung erfolgt über einen Zugangsschlüssel (Token) im HTTP-Kopf: Authorization: Bearer {zugangsschluessel} Eigenschaft Beschreibung Ausgabe Wird bei der Einrichtung auf der Zentrale erzeugt und einmalig angezeigt. Er kann danach nicht erneut angezeigt werden – geht er verloren, wird ein neuer erzeugt. Speicherung Die Zentrale speichert den Schlüssel nicht im Klartext, sondern nur einen daraus abgeleiteten Prüfwert. Recht Je Schlüssel festgelegt: Lesen oder Schreiben . Ein Schlüssel mit Recht „Schreiben“ darf auch abfragen. Standorte Je Schlüssel festgelegt, für welche Standorte er gilt. Ablauf Ohne Ablaufdatum (Voreinstellung) oder befristet, z. B. für Testzugänge. Widerruf Jederzeit auf der Zentrale möglich. Absender Optional auf bestimmte Absenderadressen beschränkbar. Der Schlüssel gehört ausschließlich in den Kopf der Anfrage, niemals in die Adresse. Adressen werden in Protokollen gespeichert, der Kopf nicht. Empfehlung: Für Systeme, die den Zustand nur anzeigen, einen Schlüssel mit Recht „Lesen“ verwenden. Wird ein solches System kompromittiert, kann die Anlage darüber nicht beeinflusst werden. 2.2 Standort-Kennung Jeder Standort einer Zentrale hat eine Standort-Kennung ( locationHash , 32 Zeichen hexadezimal). Sie wird bei der Einrichtung mitgeteilt. Die Standort-Kennung ist **keine** Berechtigung. Sie sagt nur, welcher Standort gemeint ist. Ob er gemeldet oder abgefragt werden darf, entscheidet allein der Zugangsschlüssel. Eine Meldung für einen Standort, für den der Schlüssel nicht freigegeben ist, wird abgewiesen. 2.3 Rate Limiting Parameter Wert Max. Anfragen 1 pro Sekunde je Absender, kurzzeitig bis zu 5 Bei Überschreitung HTTP 429 Ein Zutrittssystem meldet bei Zustandswechsel und höchstens ein Lebenszeichen pro Minute. Mehr Anfragen sind im Betrieb nicht vorgesehen. 3. Zustand abfragen (GET) Liefert den Zustand der Anlage für alle Standorte, für die der Schlüssel freigegeben ist. 3.1 Request GET /api/intrusion/access/state HTTP/1.1 Host: {adresse-der-zentrale} Authorization: Bearer {zugangsschluessel} Accept: application/json 3.2 Response (Erfolg) HTTP/1.1 200 OK Content-Type: application/json { "locations": [ { "locationHash": "9f2c4e7a1b3d5f6081a2c3d4e5f60718", "name": "Lagerhalle Nord", "armingState": "armed", "alarmState": "none", "fault": false, "lastReportAt": "2026-10-14T06:58:12.000Z" } ], "timestamp": "2026-10-14T07:02:40.000Z" } 3.3 Response-Felder Root-Objekt Feld Typ Beschreibung locations array Ein Eintrag je freigegebenem Standort timestamp string Zeitpunkt der Antwort (ISO 8601, UTC) locations-Objekt (Array-Element) Feld Typ Beschreibung locationHash string Standort-Kennung name string Name des Standorts armingState string Scharfzustand der Anlage (siehe Enum) alarmState string Alarmzustand der Anlage (siehe Enum) fault boolean true , wenn an diesem Standort eine Störung vorliegt – der Schnittstelle oder der Anlage (z. B. Kamera, Netzwerk) lastReportAt string | null Zeitpunkt der letzten angenommenen Meldung (ISO 8601, UTC), null wenn noch keine Meldung einging armingState Enum Wert Beschreibung armed Standort ist scharf arming Scharfschaltung läuft (Vorlaufzeit, Kameras starten) disarmed Standort ist unscharf alarmState Enum Wert Beschreibung none Kein Alarm prealarm Voralarm läuft alarm Alarm ist ausgelöst und noch nicht quittiert Scharfzustand und Alarmzustand sind bewusst zwei getrennte Felder. Der Zustand „unscharf, Alarm noch offen“ entsteht, wenn bei laufendem Alarm aufgeschlossen wird (Abschnitt 6). Den Gebäudezustand selbst (auf- oder zugeschlossen) liefert die Abfrage nicht zurück – diesen kennt das Drittsystem selbst. 4. Gebäudezustand melden (POST) Meldet der Zentrale, ob das Gebäude eines Standorts zugeschlossen oder aufgeschlossen ist. Erfordert einen Schlüssel mit Recht „Schreiben“. 4.1 Request POST /api/intrusion/access/report HTTP/1.1 Host: {adresse-der-zentrale} Authorization: Bearer {zugangsschluessel} Content-Type: application/json Accept: application/json 4.2 Request-Body { "locationHash": "9f2c4e7a1b3d5f6081a2c3d4e5f60718", "buildingLocked": true, "timestamp": "2026-10-14T06:58:12Z" } 4.3 Request-Felder Feld Typ Pflicht Beschreibung locationHash string ✓ Standort-Kennung des gemeldeten Standorts buildingLocked boolean ✓ true = Gebäude zugeschlossen, false = Gebäude aufgeschlossen timestamp string Zeitpunkt der Meldung (ISO 8601). Empfohlen – aktiviert den Wiederholschutz (Abschnitt 7.3) `buildingLocked` muss ein echter Wahrheitswert sein: `true` oder `false`. Zeichenketten wie `"true"`, Zahlen wie `1` oder fehlende Werte werden mit HTTP 400 abgewiesen. 4.4 Response (Erfolg) HTTP/1.1 200 OK Content-Type: application/json { "ok": true, "accepted": { "buildingLocked": true }, "timestamp": "2026-10-14T06:58:12.000Z" } Feld Typ Beschreibung ok boolean true , wenn die Meldung angenommen wurde accepted.buildingLocked boolean Der angenommene Gebäudezustand timestamp string Zeitpunkt der Verarbeitung (ISO 8601, UTC) „Angenommen“ heißt: Die Zentrale kennt jetzt den neuen Gebäudezustand. Ob die Anlage daraufhin geschaltet hat, zeigt die Abfrage (Abschnitt 3) – die Scharfschaltung kann je nach Regelwerk ausbleiben oder mit Vorlaufzeit erfolgen. 5. Fehlerbehandlung 5.1 HTTP-Statuscodes Code Bedeutung Beschreibung 200 OK Abfrage beantwortet bzw. Meldung angenommen 400 Bad Request Ungültiger Inhalt, buildingLocked kein Wahrheitswert, oder timestamp unlesbar, zu alt bzw. bereits verwendet 401 Unauthorized Schlüssel fehlt oder ist unbekannt 403 Forbidden Schlüssel widerrufen oder abgelaufen, Absender nicht freigegeben, Standort für diesen Schlüssel nicht freigegeben, Schlüssel nur lesend, oder Anfrage nicht verschlüsselt (http statt https) 404 Not Found Unbekannter Pfad 413 Payload Too Large Anfrage größer als 4 KB 429 Too Many Requests Rate Limit überschritten 503 Service Unavailable Schnittstelle auf der Zentrale vorübergehend nicht verfügbar 5.2 Fehler-Response { "error": "forbidden" } Fehlercode Beschreibung unauthorized Zugang abgewiesen (Schlüssel fehlt, unbekannt, widerrufen, abgelaufen oder Absender nicht freigegeben) read_only Schlüssel hat nur Leserecht forbidden Standort für diesen Schlüssel nicht freigegeben bad_request Inhalt ungültig not_found Unbekannter Pfad unavailable Schnittstelle vorübergehend nicht verfügbar Die Fehlermeldungen nach außen sind bewusst knapp und nennen nicht, woran eine Anmeldung gescheitert ist. Der genaue Grund steht im Prüfprotokoll der Zentrale und kann vom Errichter bzw. von dexa eingesehen werden. 5.3 Retry-Strategie (Drittsystem) Fehlertyp Wiederholen Wartezeit Netzwerkfehler Ja 5 s, 10 s, 30 s HTTP 503 Ja 5 s, 10 s, 30 s HTTP 429 Ja mindestens 1 s HTTP 400, 401, 403, 404 Nein – Konfiguration prüfen Bei einer Wiederholung mit Zeitstempel bitte einen neuen Zeitstempel verwenden – eine Anfrage mit bereits verwendetem Zeitstempel wird als Wiederholung abgewiesen. 6. Verhalten der Anlage Eine angenommene Meldung wirkt wie das Schalten eines Schlüsselschalters: Meldung Wirkung Aufgeschlossen ( false ) Standort wird sofort unscharf geschaltet, ohne Vorlaufzeit Zugeschlossen ( true ) Standort wird über den normalen Weg scharf geschaltet: Vorlaufzeit, Kamerastart, Kameraprüfung Gleicher Zustand wie zuvor Keine Wirkung Erste Meldung nach Einrichtung Zustand wird übernommen, es wird noch nicht geschaltet 6.1 Schutzregeln Situation Verhalten Alarm aktiv, Meldung „aufgeschlossen“ Standort wird unscharf, der Alarm bleibt unquittiert Alarm aktiv, Meldung „zugeschlossen“ Es wird nicht scharf geschaltet. Nach Quittierung des Alarms holt die Anlage die Scharfschaltung nach, wenn das Gebäude weiterhin als zugeschlossen gemeldet ist Wartung aktiv Keine Schaltwirkung, nur Protokoll Störung der Schnittstelle Keine Schaltwirkung, nur Protokoll Der zuletzt gemeldete Gebäudezustand bleibt auch über einen Neustart der Zentrale erhalten. 6.2 Lebenszeichen Anders als beim Kontakt eines Schlüsselschalters meldet sich ein Ausfall des Drittsystems nicht von selbst – ein Drahtbruch wird erkannt, ein stummes Drittsystem nicht. Deshalb kann je Zugangsschlüssel ein **Lebenszeichen** eingestellt werden: „Meldung erwartet alle … Minuten“ (Vorschlag 15 Minuten). **Jede** Anfrage zählt als Lebenszeichen, auch eine reine Abfrage – ein eigener Aufruf ist nicht nötig. Einstellung Verhalten bei ausbleibender Meldung Lebenszeichen eingestellt Die Zentrale meldet Störung und friert den Gebäudezustand ein. Der Scharfzustand bleibt unverändert – eine scharfe Anlage wird durch einen Ausfall des Drittsystems nicht unscharf. Mit der nächsten Meldung gilt wieder der gemeldete Zustand. Kein Lebenszeichen (Voreinstellung) Der zuletzt gemeldete Zustand gilt unbegrenzt weiter. Ein Ausfall des Drittsystems bleibt unbemerkt. Nur sinnvoll für Systeme, die ausschließlich bei Änderung melden können. Empfehlung: Das Drittsystem fragt in regelmäßigen Abständen den Zustand ab (Abschnitt 3) und die Zentrale wird mit Lebenszeichen betrieben. 7. Sicherheitsanforderungen 7.1 Übersicht Anforderung Beschreibung Transport Ausschließlich HTTPS. Anfragen über unverschlüsseltes HTTP werden abgewiesen. Schlüsselspeicherung Auf der Zentrale nur als abgeleiteter Prüfwert, Vergleich in konstanter Zeit Rechtetrennung Getrennte Schlüssel für Lesen und für Schreiben Standortbindung Ein Schlüssel gilt nur für die ihm zugeordneten Standorte Absenderbeschränkung Optional je Schlüssel Erreichbarkeit Voreinstellung nur internes Netz, von außen nur auf ausdrücklichen Wunsch Methoden Nur GET und POST Gehäufte Fehlversuche Ab 10 abgewiesenen Anfragen innerhalb von 10 Minuten meldet die Zentrale eine Störung an den Betreiber (Abschnitt 7.2) Prüfprotokoll Jede Anfrage wird auf der Zentrale protokolliert: Zeitpunkt, Absender, Kennung des Schlüssels, Standort, Aktion, Ergebnis. Der Schlüssel selbst wird nie protokolliert. 7.2 Gehäufte Fehlversuche Die Zentrale sperrt nicht , sondern meldet : Werden innerhalb von 10 Minuten 10 Anfragen wegen ungültigem Zugangsschlüssel, fehlender Berechtigung oder nicht freigegebenem Standort abgewiesen, setzt sie eine Störung und benachrichtigt den Betreiber mit den Absenderadressen. Die Störung endet 60 Minuten nach dem letzten Fehlversuch. Bewusst keine Sperre: Eine Sperre würde auch ein falsch eingerichtetes Drittsystem aussperren – oder ein korrektes System, das hinter derselben Internetadresse wie ein Angreifer liegt. Dann kämen auch echte Meldungen wie „aufgeschlossen“ nicht mehr an. Die Meldung macht Angriffe und Fehlkonfiguration sichtbar, ohne den Betrieb zu blockieren. Durchprobieren ist durch die Länge des Zugangsschlüssels und die Begrenzung auf 1 Anfrage pro Sekunde praktisch ausgeschlossen. Während die Störung besteht, liefert die Abfrage (Abschnitt 3) für alle Standorte "fault": true . 7.3 Wiederholschutz Wird ein timestamp mitgesendet, prüft die Zentrale: Er darf höchstens 5 Minuten von der Uhrzeit der Zentrale abweichen. Derselbe Zeitstempel wird je Schlüssel nur einmal angenommen. Damit kann eine mitgeschnittene Anfrage nicht später erneut eingespielt werden. Ohne timestamp entfällt dieser Schutz für die betreffende Anfrage; die Uhr des Drittsystems sollte deshalb über NTP synchronisiert sein und der Zeitstempel immer mitgesendet werden. 8. Beispiel: Vollständiger Ablauf 8.1 Schritt 1: Gebäude wird abends zugeschlossen curl -X POST "https://{adresse-der-zentrale}/api/intrusion/access/report" \ -H "Authorization: Bearer {zugangsschluessel}" \ -H "Content-Type: application/json" \ -d '{ "locationHash": "9f2c4e7a1b3d5f6081a2c3d4e5f60718", "buildingLocked": true, "timestamp": "2026-10-14T18:05:00Z" }' Response: { "ok": true, "accepted": { "buildingLocked": true }, "timestamp": "2026-10-14T18:05:00.412Z" } 8.2 Schritt 2: Scharfschaltung prüfen curl -X GET "https://{adresse-der-zentrale}/api/intrusion/access/state" \ -H "Authorization: Bearer {zugangsschluessel}" \ -H "Accept: application/json" Response während der Vorlaufzeit: { "locations": [ { "locationHash": "9f2c4e7a1b3d5f6081a2c3d4e5f60718", "name": "Lagerhalle Nord", "armingState": "arming", "alarmState": "none", "fault": false, "lastReportAt": "2026-10-14T18:05:00.412Z" } ], "timestamp": "2026-10-14T18:05:20.000Z" } Nach Ablauf der Vorlaufzeit wechselt armingState auf armed . 8.3 Schritt 3: Gebäude wird morgens aufgeschlossen curl -X POST "https://{adresse-der-zentrale}/api/intrusion/access/report" \ -H "Authorization: Bearer {zugangsschluessel}" \ -H "Content-Type: application/json" \ -d '{ "locationHash": "9f2c4e7a1b3d5f6081a2c3d4e5f60718", "buildingLocked": false, "timestamp": "2026-10-15T06:30:00Z" }' Der Standort wird sofort unscharf; die Abfrage liefert danach "armingState": "disarmed" . 9. Einrichtung Schritt Wer Inhalt 1 Errichter / dexa Auf der Zentrale eine Zutrittskontroll-Schnittstelle vom Typ „API“ anlegen 2 Errichter / dexa Zugangsschlüssel erzeugen: Standorte, Recht, optional Lebenszeichen, Absender, Ablauf 3 Errichter / dexa Adresse, Standort-Kennung(en) und Zugangsschlüssel sicher an den Errichter des Drittsystems übergeben 4 Errichter Drittsystem Schnittstelle einrichten, Abfrage testen, dann Meldungen „zu“ und „auf“ testen 5 Beide Ergebnis über die Abfrage und das Prüfprotokoll der Zentrale gemeinsam kontrollieren Anhang A: Constraints Feld Constraint locationHash 32 Zeichen, hexadezimal ( 0-9 , a-f ), Groß-/Kleinschreibung egal buildingLocked JSON-Wahrheitswert true oder false timestamp ISO 8601, höchstens 5 Minuten Abweichung zur Zentrale, je Schlüssel nur einmal verwendbar Größe einer Anfrage Max. 4 KB Methoden GET, POST Anfragerate 1 pro Sekunde je Absender, kurzzeitig bis zu 5 API-Anforderungen für Telemetrie-Upload Version: 2.0 Stand: 2026-07-13 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: Bearer Token (JWT) Authorization: Bearer Authorization: Bearer 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, beispielsweise "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 beziehungsweise "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 in der Regel 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 (beispielsweise "0.000000" ) smokeLevel Raucherkennungsgrad string float-String (beispielsweise "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 beziehungsweise "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" } ] } ] } API-Beschreibung für Telemetrie-Abruf (GET) Version: 1.6 Stand: 2026-06 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/telemetry (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 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 https:///api/health/telemetry = IP oder Hostname der Zentrale im lokalen Netz (beispielsweise 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/telemetry und /api/health/telemetry/ sind gleichwertig). 3. Request Es wird kein Request-Body gesendet. Erforderlicher Header: Header Pflicht Wert Authorization ja Bearer Beispiel: curl --location 'https://192.168.1.16/api/health/telemetry/' \ --header 'Authorization: Bearer ' 4. Payload-Struktur (Response) Root ├── timestamp ├── fireStation ├── deviceId └── objects[] ├── type (vehicle | room | hall) ├── vehicleId ├── licencePlate ├── 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, beispielsweise "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. 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 beziehungsweise "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 8.1) licencePlate 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", "licencePlate": "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 0 – 9 oder leer teams Reserviert string in der Regel 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 8.2) operationTime Betriebszeit (Tage) string numerisch, 0–9999 dirtLevel Verschmutzungsgrad string float-String (beispielsweise "0.000000" ) smokeLevel Raucherkennungsgrad string float-String (beispielsweise "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 , licencePlate 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 beziehungsweise "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 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. Vollständiges Response-Beispiel { "timestamp": "2026-06-09T11: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" } ] } ] } Funktionserfüllung Safe Fire House Anlage Alle Infos finden Sie unter https://dexa.gmbh 1. Alleinstellungsmerkmale (in Kombination) System ausgelegt für Einsatz in (Einsatz-)Fahrzeugen. Kein manueller Eingriff bei Aus- und Einrücken von Fahrzeugen, kein "leer ziehen der Batterien". Multistandortfähigkeit, Fahrzeuge werden an allen Standorten überwacht, Alarme werden mit Standort übertragen. Bidirektionale vollwertige Schnittstellenanbingung, rückmeldeabhängiger Alarmüberlauf und Redundanz. Kein "fire and forget", Integration in alle BOS-Systeme mit Leitstellenanbindung. Ohne Cloud-Dienste betreibbar. Leise und stumme Melder (Sensoren). Als einziges System für den Einsatz in (Einsatz-)Fahrzeugen von einer staatlichen Prüfstelle geprüft und testiert (Prüfstelle für Brandschutztechnik des österreichischen Bundesfeuerwehrverbandes. Prüfbericht hier herunterladen 2. Preiskalkulation Angebot eines All-Inklusive-Preises, unabhängig von Anzahl, Art und Beschaffenheit der Komponenten, Standorte oder Fahrzeuge. Preis unabhängig von Kommunikationsschnittstellen oder auszuführenden Aktionen – stets inkludiert – als Pauschalpreis pro Fahrzeug, Halle oder Raum, mit Bruttopreissumme. Inkludierung aller Service-Nebenkosten und Stundensätze, außer Reisekosten. Keine laufenden bzw. konsumtiven Kosten oder Lizenzen. Inkludierung aller Kosten für laufenden Betrieb, Projektierung, Programmierung, Installation, Inbetriebnahme und Dokumentation. 3. Systemaufbau Modularer, individueller und flexibler Aufbau entsprechend den Anforderungen von Fahrzeugen und Standorten. Verwendung namhafter Komponentenhersteller Betrieb ausschließlich on-premise (nicht cloud-basiert). Keine Abhängigkeit von Mobilfunk- oder Clouddiensten bei der Verbindung von Meldern/Sensoren zu Alarmsystemen, oder Angebot einer gleichwertigen lokalen Redundanz. Permanente Überwachung aller Komponenten und Kommunikationswege, die größtenteils redundant ausgelegt werden müssen. Ausführbar als Mehr-Standort-Lösung, sprich standortübergreifende Überwachung von Fahrzeugen ohne manuellen Eingriff, ohne An- oder Abmelden bzw. An- oder Ablernen. Alarmierung inklusive aktueller Standortdaten (Rauchalarm in Fahrzeug X, Melder Y, aktuell an Standort Z). Keine manuelle Eingriffsnotwendigkeit bei Verlassen des Standortes, keine Notwendigkeit zu quittieren. Auch bei Wechsel des Fahrzeugs an einen anderen überwachten Standort. Kein Eingriff in die Fahrzeugelektronik notwendig. Anlage nahtlos erweiterbar von 1 Fahrzeug (bzw. Halle oder Raum) an 1 Standort bis zu 1.000 Fahrzeugen (bzw. Halle oder Raum) an 200 Standorten. TCP/IP-Kommunikation als Grundarchitektur, alle Kommunikationswege (auch Funk) sind bidirektional, verschlüsselt und protokollierbar auszuführen. Ausführung aller IT-Komponenten in PoE. Anbindungsmöglichkeit an alle gängigen Leitstellensysteme aus dem BOS-Bereich. Anbindungsmöglichkeit an Brandmeldeanlagen über potenzialfreien Schaltkontakt. Aufschaltung auf eine Kreisleitstelle mit behördlicher Genehmigung im Rahmen der geltenden Aufschaltbedingungen möglich. Auslegung der Anlage als Gefahrenwarnanlage in Anlehnung an VDE 0826. Anbindungsmöglichkeit an gängige Gebäudeleitsysteme (BUS- oder TCP/IP-basiert). Schriftliche Bestätigung des Herstellers des Gesamtsystems, dass es zum Einsatzzweck der Überwachung der Fahrzeuginnenräume geeignet ist, zur Haftungssicherheit. Testat einer namhaften Prüforganisation über die Eignung zum Einsatz in Einsatzfahrzeugen. Regel-Lebensdauer der Anlage von bis zu 10 Jahren, wartungsfrei. 4. Branderkennung und Alarmverarbeitung Zentrales Alarmmanagement Photoelektrische Erkennung Batterielebensdauer: ausgelegt auf bis zu 10 Jahre Kommunikationsprotokolle: bidirektionales Funkband (z. B. 868 MHz) und TCP/IP Verschlüsselung: AES (mind. 128 Bit), optional HMAC Reichweite: bis zu 300 m (Freifeld), mehrfach erweiterbar durch Repeater Zertifizierungen der Rauchmelder (nur bei Meldern in Gebäuden, nicht in Fahrzeugen): VdS, Q-Label, DIN EN 14604/14676 Schutzklassen: IP20 bis IP44 (je nach Komponente) Alarmierung: Piezo-Signalgeber (85 dB/3 m), zusätzlich auch ausführbar in leise (50 dB/3 m) und stumm (Optional): Server-Variante (Central Unit Pro) zur Installation in einem 19-Zoll Server-Rack für große Installationen zur Virtualisierung des Systems. Selbstkalibrierend Selbsttestfunktion, Watchdog-Funktion, zentrale Batterieüberwachung Hochpräzise Sensoren für Partikelerkennung, erweiterter Insektenschutz LED-Notbeleuchtung bei Alarm Autarker Betrieb der Rauchsensoren bei Zentralenausfall – lokale Alarmierung weiter möglich (Optional): Infrastrukturmodul: Schaltkasten oder mobiler Koffer mit unterbrechungsfreier Batteriepufferung (USV) bis zu 72 Stunden und redundanter Internetanbindung (WAN + LTE/5G) im M2M-Betrieb für höchste Ausfallsicherheit. (Optional): Alarmsirene: Externe LED-Alarmsirene zur optischen und akustischen Signalisierung, außeninstallationstauglich (IP44), Batterie-/Solar- oder 230V-Betrieb, mit integrierter Blitzleuchte (Optional): Schaltkontakt: Potenzialfreier Schaltkontakt zur Anbindung von Brandmeldeanlagen und Gebäudeleittechnik, verfügbar als 1-fach und 4-fach Variante mit bis zu 4 Eingangs- und 4 Ausgangskanälen Erweiterte API-Unterstützung: REST-API (POST/PUT/GET), MQTT optional, Webhooks Bidirektionale Anbindung von Schnittstellen: Alle gängigen Alarmsysteme aus dem BOS-Bereich, z. B. DIVERA24/7, Alamos, Groupalarm, Dräger, WeberRescue, Feuersoftware, Fireboard, Feuernetz, DE-Alarm, alarmdispatcher, FF-Agent, Handyalarm.com, Solaris/Blaulicht SMS, … Anbindung an Verwaltungssysteme wie Fireplan, Solaris, FWPortal, MPFeuer Wartungsinformationen als Schnittstellenanbindung zu Flottenmanagement- und Rettungsdienst-Systemen, z. B. ZF Rescue Connect, Dräger Smart Rescue System, Weber Rescue RetterAlarm Alarmanbindung durch Softwareschnittstellen für TR-BOS-konforme digitale Meldeempfänger, zum Beispiel über LTE (Swissphone oder Oelmann Electronics) über die Dexa Pager Plattform Leitstellenanbindung: gängige Leitstellensysteme, z. B. ISE Cobra4, CKS Celios, VivaSecur LVS, ELIS, Hexagon, … Schaltanbindung an Brandmeldeanlagen über potenzialfreien Schaltkontakt Niederschwellige Alarmwege wie Telefonansage mit Rückmeldestatus, SMS, E-Mail Alarmüberlauf auf andere Gruppen und Schnittstellen, abhängig von Rückmeldungen der alarmierten Einheiten Mindestens wöchentlicher Statusbericht bei Nichterreichbarkeit von Schnittstellen oder Komponenten Mindestens monatlicher Statusbericht über alle Komponenten mit Batterieständen, Verschmutzungsgraden und weiteren Zuständen Sichere Anbringung in Fahrzeugen (z. B. 3M Dual-Lock o.ä.) oder Verschraubung Gebäudeleittechnik: anbindbar mit TCP/IP, Webhooks, an KNX, Home Assistant, Symcon, DALI, BACnet, MODBUS (Optional): Mini-Display mit E-Ink-Technologie zur Alarmanzeige, auch als konfigurierbares Taster-Element nutzbar, 230V-stromversorgt (Optional): Fest installierbares Netzwerkdisplay (PoE) zur Alarmanzeige, Steuerung und Überwachung der Anlage in verschiedenen Größen und Formfaktoren, versorgt über PoE, mit Möglichkeit zur Alarmquittierung, Anlagenkonfiguration und Unscharfschaltung Netzwerkkompatibilität im Enterprise-Umfeld, Firewall-Betrieb (z. B. Sophos) Grafische Bedienoberfläche aus internem und externem Netzwerk über Internetfreigabe (verschlüsselt und geschützt) erreichbar. Umfangreiche Zustandsüberwachung und Steuerung über digitales Bedientableau und grafische Oberfläche (GUI) möglich. 5. Installation und Inbetriebnahme Durchführung durch erfahrene technische Angestellte mit Erfahrung in TGA-, ITK-Systemen und/oder Fahrzeugtechnik Individuelle standortabhängige Programmierung Vorab-Tests und Simulationen zur Funktionssicherung Schulungen für Bedienpersonal, Wartungstechniker und IT-Administratoren 6. Dokumentation und Güte Vollständige technische Dokumentation: Installation, Betriebstest, Messwerte, Konfiguration, Nachweis eines Alarmtests Positiver Prüfbericht einer namhaften Prüfstelle für Brandschutztechnik, in diesem Falle der Prüfstelle für Brandschutztechnik des Österreichischen Bundesfeuerwehrverbandes (Prüfbericht-Nr. FT 14/953/25, gültig bis 02.12.2027). 7. Service Dediziertes Supportteam, optional Vor-Ort-Service und Remote-Unterstützung Umfassende Möglichkeiten zur Fernwartung Optionale Möglichkeit zum Abschluss einer Wartungsvereinbarung für erweiterte Funktionalitäten und externes Monitoring der Anlagenverfügbarkeit Zentrales Service-Logbuch zur Überwachung der Systemzuverlässigkeit durch Anbieter