iobroker.waip-web 0.7.16 → 0.7.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.de.md CHANGED
@@ -10,6 +10,21 @@ Verbindet sich per Socket.IO mit einem WAIP-Web-Wachalarm-Monitor und bildet
10
10
  Einsätze, Rückmeldungen, Routen und TTS-Ansagen als ioBroker-States ab –
11
11
  ohne dass ein Browser-Tab dauerhaft offen sein muss.
12
12
 
13
+ ## Inhaltsverzeichnis
14
+
15
+ - [Über diesen Adapter](#über-diesen-adapter)
16
+ - [Über WAIP-Web](#über-waip-web)
17
+ - [Praktische Anwendungsfälle](#praktische-anwendungsfälle)
18
+ - [Funktionen](#funktionen)
19
+ - [Warum ein Session-Cookie nötig ist](#warum-ein-session-cookie-nötig-ist)
20
+ - [Konfiguration](#konfiguration)
21
+ - [States (unter `waip-web.0.*`)](#states-unter-waip-web0)
22
+ - [info](#info) · [status](#status) · [einsatz](#einsatz) ·
23
+ [einsatz.json](#einsatzjson) · [einsatz.tts](#einsatztts) ·
24
+ [debug](#debug)
25
+ - [Logging](#logging)
26
+ - [Lizenz und Changelog](#lizenz-und-changelog)
27
+
13
28
  ## Über diesen Adapter
14
29
 
15
30
  Dieser Adapter ist ein **inoffizielles Community-Projekt** und steht in
@@ -53,10 +68,61 @@ lizenziert. Dieser Adapter enthält keinen Code aus dem WAIP-Web-Projekt,
53
68
  sondern implementiert eine eigenständige Anbindung an dessen Socket.IO-
54
69
  Schnittstelle.
55
70
 
71
+ ## Praktische Anwendungsfälle
72
+
73
+ In diesem Abschnitt geht es darum, was sich mit den States dieses Adapters
74
+ konkret **bauen** lässt – typischer Einsatz auf einer Feuerwehr-/
75
+ Rettungsdienst-Wache:
76
+
77
+ - **Wandmontierte Alarmanzeige.** `einsatz.json.current` an ein
78
+ VIS-Tabellen-Widget auf einem wandmontierten Tablet/TV im Aufenthalts-
79
+ raum oder in der Fahrzeughalle binden – Einsatzart, Stichwort, Adresse
80
+ und alarmierte Einsatzmittel erscheinen automatisch, ohne dass dort
81
+ dauerhaft ein Browser-Tab offen gehalten werden muss (genau dafür
82
+ existiert dieser Adapter).
83
+ - **Automationen direkt bei Alarmeingang auslösen.** `einsatz.alarmAktiv`
84
+ (ggf. zusammen mit `info.connection`) in einem Script/einer Blockly-Regel
85
+ beobachten, um bei Alarm Licht in der Fahrzeughalle einzuschalten, ein
86
+ Tor/eine Tür zu öffnen, eine Push-Benachrichtigung (z. B. über einen
87
+ Telegram-/Pushover-Adapter) mit `einsatz.stichwort` + `einsatz.ort` zu
88
+ versenden oder eine Lichtszene auszulösen – wenige Sekunden nach der
89
+ eigentlichen Alarmierung, da ioBroker-State-Änderungen sofort feuern und
90
+ kein Polling nötig ist.
91
+ - **Alarm laut ansagen.** `einsatz.tts.last` ist eine fertige, absolute
92
+ mp3-URL; eine `sonos`-/`snapcast`-/`text2speech`-Automation darauf
93
+ ansetzen (oder die URL direkt abspielen), um den Einsatz über
94
+ Gebäudelautsprecher anzusagen, sobald `io.playtts` feuert – hilfreich,
95
+ wenn nicht alle Mitglieder gerade auf einen Bildschirm schauen.
96
+ - **Live-Übersicht der Rückmeldungen.** Die `einsatz.rueckmeldungAnzahl.*`
97
+ Zähler (pro Rolle: EK/GF/ZF/VF, pro Zusatzfunktion: AGT/FZF/MA/MED)
98
+ aktualisieren sich in Echtzeit, sobald Einsatzkräfte per App
99
+ zurückmelden – als Gauge- oder Zahlen-Widget gebunden ergibt das eine
100
+ Übersicht auf einen Blick, wer bereits kommt.
101
+ - **Nachbereitung/Statistik.** `einsatz.json.history10` hält die letzten
102
+ 10 abgeschlossenen Einsätze als flache Tabelle vor – an eine zweite
103
+ VIS-Ansicht binden oder periodisch exportieren (z. B. per Script, das
104
+ den State bei `io.standby` ausliest), um ein längerfristiges Log zu
105
+ führen oder Einsatzzahlen in ein Statistik-/Dashboard-Adapter
106
+ einzuspeisen.
107
+ - **Routen-/Fahrzeugübersicht auf einer Karte.** `einsatz.json.routen`
108
+ enthält für jede alarmierte Wache `lat`/`lon` und `color` – an ein
109
+ VIS-Kartenwidget gebunden ergibt das auf einen Blick, wer unterwegs ist,
110
+ unabhängig von der WAIP-Web-eigenen Karte.
111
+ - **Anbindung an weitere ioBroker-Automationen.** Da jedes Feld ein
112
+ gewöhnlicher ioBroker-State ist, lässt sich das Ganze mit allem
113
+ kombinieren, was ohnehin in der Instanz läuft – `einsatz.*` in eine
114
+ Smart-Home-Szenensteuerung einspeisen, eine Grafana-/InfluxDB-Historie
115
+ für Reaktionszeit-Auswertungen führen, oder per ioBroker-MQTT-Adapter
116
+ in einen Node-RED-artigen Flow einbinden, ganz ohne eigene Anbindung an
117
+ die WAIP-Web-API.
118
+
56
119
  ## Funktionen
57
120
 
58
121
  - Verbindung zum Namespace `/waip` per `socket.io-client`, Registrierung
59
- über `emit('WAIP', monitorId)` (3-faches Emit für Robustheit)
122
+ über `emit('WAIP', monitorId)` einmalig (verlässt sich als Fallback
123
+ auf `REGISTRATION_TIMEOUT_MS` statt auf wiederholte Emits, da ein
124
+ redundanter Emit den Server nur erneut antworten lässt, ohne die
125
+ Zustellungssicherheit zu erhöhen)
60
126
  - Manuelles Reconnect-Handling (kein Auto-Reconnect der Bibliothek) mit
61
127
  konfigurierbarer Verzögerung
62
128
  - Registrierungs-Timeout mit Audit-Log (`debug.monitorAudit`)
@@ -90,6 +156,9 @@ Schnittstelle.
90
156
  ab, sobald seine `ablaufzeit` um mehr als eine Gnadenfrist (60
91
157
  Sekunden) überschritten ist, statt unbegrenzt veraltete "aktiv"-Daten
92
158
  stehen zu lassen.
159
+ - Zeigt immer nur den zuletzt aktiven Einsatz; mehrere gleichzeitig
160
+ laufende Einsätze sind aktuell nur über das Dashboard der
161
+ WAIP-Web-Instanz selbst einsehbar
93
162
 
94
163
  ### Warum ein Session-Cookie nötig ist
95
164
 
@@ -157,6 +226,27 @@ damit ein verlässlicher Schalter dafür, ob hier gerade echte Live-Daten
157
226
  stehen. Der zuletzt abgeschlossene Einsatz bleibt trotzdem über
158
227
  `einsatz.json.history10` abrufbar:
159
228
 
229
+ > **Hinweis:** Der Adapter bildet immer nur den zuletzt aktiv gemeldeten
230
+ > Einsatz ab (`einsatz.*` bzw. `einsatz.json.current`) – analog zum
231
+ > Alarmmonitor des offiziellen WAIP-Web-Frontends. Theoretisch können in
232
+ > WAIP-Web mehrere Einsätze gleichzeitig aktiv sein (z. B. wenn kurz
233
+ > hintereinander zwei Alarmierungen eingehen). Diese States sind **kein
234
+ > Array mehrerer laufender Einsätze**, sondern werden bei jedem neuen
235
+ > `io.new_waip`-Event überschrieben – ein zeitgleich zweiter laufender
236
+ > Einsatz ist über den Adapter aktuell nicht sichtbar. Eine vollständige
237
+ > Übersicht aller gerade aktiven Einsätze liefert derzeit nur das
238
+ > Dashboard der angebundenen WAIP-Web-Instanz selbst.
239
+
240
+ > **Hinweis:** WAIP-Web befüllt `einsatznummer`, `objekt`/`objektteil`,
241
+ > `besonderheiten`, `strasse`/`hausnummer`, `einsatzdetails` sowie das
242
+ > Berechtigungsflag serverseitig nur für **eingeloggte** Clients
243
+ > (`db_user_check_permission_for_waip()` im server-eigenen
244
+ > `server/waip.js`) – da dieser Adapter sich bewusst ohne Login
245
+ > verbindet (siehe [Über diesen Adapter](#über-diesen-adapter)), sendet
246
+ > der Server diese Felder immer leer bzw. `false`. Sie werden deshalb
247
+ > gar nicht erst als States geführt, statt dauerhaft leere Werte
248
+ > vorzuhalten.
249
+
160
250
  | State | Typ | Beschreibung |
161
251
  | --- | --- | --- |
162
252
  | `alarmAktiv` | boolean | `true` seit dem letzten `io.new_waip`, `false` seit dem letzten `io.standby` |
@@ -167,15 +257,9 @@ stehen. Der zuletzt abgeschlossene Einsatz bleibt trotzdem über
167
257
  | `stichwort` | string | Alarmstichwort |
168
258
  | `ort` | string | Ort |
169
259
  | `ortsteil` | string | Ortsteil (falls abweichend vom Ort) |
170
- | `strasse` / `hausnummer` | string | Adresse |
171
- | `objekt` / `objektteil` | string | Gebäude-/Objektname und -teil |
172
- | `einsatzdetails` | string | Zusatzdetails (nur bei Brand-/Hilfeleistungseinsätzen befüllt) |
173
- | `besonderheiten` | string | Freitext-Besonderheiten der Leitstelle |
174
260
  | `zeitstempel` | string (date) | Alarmzeit |
175
261
  | `ablaufzeit` | string (date) | Ende der Standby-Anzeigedauer, Basis für `restzeit` |
176
- | `einsatznummer` | string | Einsatznummer (sofern vom Server vergeben) |
177
262
  | `sondersignal` | number | `1` = Sondersignal, sonst kein Sondersignal |
178
- | `permissions` | string | Berechtigungsflag der Registrierung (Vollzugriff auf Detailkarte ja/nein); wird immer als String gespeichert (z.B. `"true"`), da der Server hier ein rohes Boolean sendet |
179
263
  | `latitude` / `longitude` | number | Position des Einsatzortes (normalisiert aus wgs84-Feldern oder GeoJSON-Mittelpunkt) |
180
264
  | `routenGesamt` | number | Anzahl Routen im aktuellen Einsatz |
181
265
  | `rueckmeldungGesamt` | number | Rückmeldungen gesamt im aktuellen Einsatz |
@@ -196,13 +280,13 @@ ein einfaches `{routen, rueckmeldungen, ...}`-Objekt werden von diesen
196
280
  Widgets in der Regel nicht dargestellt). `routen`/`rueckmeldungen`/
197
281
  `emAlarmiert`/`emWeitere` enthalten immer nur die Daten des **aktuellen**
198
282
  Einsatzes – sie werden bei `io.standby` geleert (`[]`) und sind **nicht**
199
- Teil der History. `permissions` innerhalb von `current`/`history10` wird
200
- genauso als String gespeichert wie im eigenständigen
201
- `einsatz.permissions`-State.
283
+ Teil der History. Wie bei `einsatz.*` oben gilt auch hier: `current`
284
+ enthält immer nur den zuletzt aktiven Einsatz – siehe Hinweis im
285
+ Abschnitt [`einsatz`](#einsatz).
202
286
 
203
287
  | State | Typ | Beschreibung |
204
288
  | --- | --- | --- |
205
- | `current` | string (JSON-Array) | Flache Daten des aktuellen Einsatzes: dieselben 19 Felder wie die einzelnen `einsatz.*`-States oben (`id` … `permissions`, plus `lat`/`lon`), gebündelt als ein Objekt innerhalb eines Arrays mit einem Element (`[]` falls kein Einsatz aktiv) – der Array-Wrapper ist nötig, weil die meisten Tabellen-Widgets am Root ein Array statt eines nackten Objekts erwarten |
289
+ | `current` | string (JSON-Array) | Flache Daten des aktuellen Einsatzes: dieselben 11 Felder wie die einzelnen `einsatz.*`-States oben (`id` … `zeitstempel`, plus `lat`/`lon`), zusätzlich `registeredMonitor`/`registeredMonitorName` (der Monitor, auf den der Adapter zu diesem Zeitpunkt registriert war), gebündelt als ein Objekt innerhalb eines Arrays mit einem Element (`[]` falls kein Einsatz aktiv) – der Array-Wrapper ist nötig, weil die meisten Tabellen-Widgets am Root ein Array statt eines nackten Objekts erwarten |
206
290
  | `history10` | string (JSON-Array) | Letzte 10 abgeschlossenen Einsätze, gleiches Schema wie `current`, ein Array-Eintrag pro Einsatz, geschrieben bei `io.standby` |
207
291
  | `routen` | string (JSON-Array) | Routen des aktuellen Einsatzes; jeder Eintrag hat `nr_wache`, `name_wache`, `color`, `lat`, `lon` (`position` zu flachem `lat`/`lon` aufgelöst) |
208
292
  | `rueckmeldungen` | string (JSON-Array) | Rückmeldungen des aktuellen Einsatzes, wie vom Server empfangen |
@@ -225,8 +309,8 @@ relevant, deshalb wird nur die jeweils letzte vorgehalten.
225
309
 
226
310
  | State | Typ | Beschreibung |
227
311
  | --- | --- | --- |
228
- | `lastEvent` | string (JSON) | Letztes empfangenes Socket-Event (Name + Zeitstempel), zur Verbindungsdiagnose |
229
- | `normalizedPosition` | string (JSON) | Ergebnis der Geodaten-Normalisierung für das letzte `io.new_waip`-Event, als flaches `{lat, lon}`-Objekt (beide `null`, falls keine gültige Position ermittelt werden konnte) |
312
+ | `lastEvent` | string (JSON-Array) | Letztes empfangenes Socket-Event (Name + Zeitstempel), zur Verbindungsdiagnose; einelementiges Array (`[]` falls noch keins), für VIS-Tabellen-Kompatibilität |
313
+ | `normalizedPosition` | string (JSON-Array) | Ergebnis der Geodaten-Normalisierung für das letzte `io.new_waip`-Event, als flaches einelementiges `[{lat, lon}]`-Array (beide `null`, falls keine gültige Position ermittelt werden konnte; `[]` falls noch kein Event), für VIS-Tabellen-Kompatibilität |
230
314
  | `rawPayloadShort` | string | Vorschau (500 Zeichen) der rohen, unnormalisierten `io.new_waip`-Nutzlast |
231
315
  | `ignoredCount` | number | Anzahl verworfener Events (Payload nannte explizit eine andere Monitor-ID) |
232
316
  | `monitorAudit` | string (JSON-Array) | Chronologisches Log von Connect-/Registrierungs-/Reconnect-Ereignissen (200 Einträge) |
@@ -234,8 +318,22 @@ relevant, deshalb wird nur die jeweils letzte vorgehalten.
234
318
  | `lastError` | string | Letzte vom Server gemeldete Fehlermeldung (`io.error`); reiner Text, kein JSON, da der Server hier einen bloßen String sendet |
235
319
  | `serverVersion` | string | Zuletzt gemeldete Server-Instanz-ID (`io.version`); Änderung deutet auf Server-Neustart hin |
236
320
 
321
+ ## Logging
322
+
323
+ Sämtliche Log-Texte sind auf Englisch, unabhängig von der ioBroker-
324
+ Systemsprache (nur UI-Texte wie Admin-Beschriftungen werden übersetzt).
325
+ Wiederkehrbare Fehlerzustände (Session-Cookie-Erneuerung,
326
+ WAIP-Registrierung, die Socket.IO-Verbindung, eine Flut von
327
+ Falscher-Monitor-Events) werden beim ersten Auftreten einmalig auf `warn`
328
+ geloggt, danach solange sie bestehen nur noch auf `debug`, und bei
329
+ Erholung einmalig auf `info` – entsprechend der
330
+ [offiziellen ioBroker-Logging-Richtlinie](https://github.com/ioBroker/ioBroker.docs/blob/master/docs/en/dev/adapterdev.md#logging).
331
+
332
+ Eine vollständige Referenz aller Log-Meldungen (gruppiert nach Level, mit
333
+ Ursache und Beispieltext) gibt es in **[LOGGING.md](LOGGING.md)** (auf
334
+ Englisch, wie auch der Quelltext des Adapters selbst).
237
335
 
238
- ---
336
+ ## Lizenz und Changelog
239
337
 
240
338
  Lizenz und vollständiges Changelog stehen in der
241
339
  [englischen README](README.md#license) (`## License`, `## Changelog`).
package/README.md CHANGED
@@ -19,6 +19,22 @@ Connects via Socket.IO to a WAIP-Web dispatch monitor and mirrors incidents
19
19
  announcements into ioBroker states – without needing a browser tab to stay
20
20
  open.
21
21
 
22
+ ## Table of contents
23
+
24
+ - [About this adapter](#about-this-adapter)
25
+ - [About WAIP-Web](#about-waip-web)
26
+ - [Practical use cases](#practical-use-cases)
27
+ - [Features](#features)
28
+ - [Why a session cookie is needed](#why-a-session-cookie-is-needed)
29
+ - [Configuration](#configuration)
30
+ - [States (under `waip-web.0.*`)](#states-under-waip-web0)
31
+ - [info](#info) · [status](#status) · [einsatz](#einsatz) ·
32
+ [einsatz.json](#einsatzjson) · [einsatz.tts](#einsatztts) ·
33
+ [debug](#debug)
34
+ - [Logging](#logging)
35
+ - [Changelog](#changelog)
36
+ - [License](#license)
37
+
22
38
  ## About this adapter
23
39
 
24
40
  This adapter is an **unofficial community project** and has no connection
@@ -61,10 +77,56 @@ WAIP-Web itself is licensed under
61
77
  This adapter contains no code from the WAIP-Web project; it implements an
62
78
  independent client for its Socket.IO interface.
63
79
 
80
+ ## Practical use cases
81
+
82
+ This section is about what you can actually *build* with the states this
83
+ adapter provides – typical use in a fire station/EMS environment:
84
+
85
+ - **Wall-mounted alarm display.** Bind `einsatz.json.current` to a VIS
86
+ table widget on a wall-mounted tablet or TV in the day room/vehicle
87
+ hall – incident type, keyword, address and alerted resources appear
88
+ automatically, without anyone having to keep a browser tab open on that
89
+ screen (which is the whole reason this adapter exists in the first
90
+ place).
91
+ - **Trigger automations the instant an alarm comes in.** Watch
92
+ `einsatz.alarmAktiv` (or `info.connection` together with it) in a
93
+ script/blockly rule to switch on lights in the vehicle hall, open a
94
+ gate/door, send a push notification (e.g. via a Telegram/Pushover
95
+ adapter) with `einsatz.stichwort` + `einsatz.ort`, or flash a
96
+ smart-light scene – all a few seconds after the actual pager alert,
97
+ no polling required since ioBroker state changes fire instantly.
98
+ - **Announce the alarm out loud.** `einsatz.tts.last` is a ready-to-play
99
+ absolute mp3 URL; point a `sonos`/`snapcast`/`text2speech`-style
100
+ automation at it (or just play the URL directly) to have the incident
101
+ announced over building speakers the moment `io.playtts` fires –
102
+ useful where members aren't all looking at a screen.
103
+ - **Live headcount / feedback board.** The `einsatz.rueckmeldungAnzahl.*`
104
+ counters (per role: EK/GF/ZF/VF, per qualification: AGT/FZF/MA/MED)
105
+ update in real time as responders confirm via the app – bind them to
106
+ gauge or number widgets for an at-a-glance "who's coming" overview
107
+ during the response.
108
+ - **Post-incident review / statistics.** `einsatz.json.history10` keeps
109
+ the last 10 completed incidents as a flat table – bind it to a second
110
+ VIS view or export it periodically (e.g. via a script reading the
111
+ state on `io.standby`) to keep a longer-running log or feed incident
112
+ counts into a dashboard/statistics adapter.
113
+ - **Route/vehicle overview on a map.** `einsatz.json.routen` carries
114
+ each responding station's `lat`/`lon` and `color` – bind it to a VIS
115
+ map widget for a quick visual of who is en route, independent of the
116
+ WAIP-Web map itself.
117
+ - **Bridge into other ioBroker automations.** Because every field is a
118
+ plain ioBroker state, it composes with anything else already running
119
+ in the instance – forward `einsatz.*` into a smart-home scene engine,
120
+ a Grafana/InfluxDB history for response-time analysis, or a
121
+ Node-RED-style flow via the ioBroker MQTT adapter, without writing a
122
+ single line against the WAIP-Web API.
123
+
64
124
  ## Features
65
125
 
66
126
  - Connects to the `/waip` namespace via `socket.io-client`, registers via
67
- `emit('WAIP', monitorId)` (emitted 3× for robustness)
127
+ `emit('WAIP', monitorId)` once (relies on `REGISTRATION_TIMEOUT_MS`
128
+ as a fallback rather than repeated emits, since a redundant emit only
129
+ makes the server reply again without improving delivery reliability)
68
130
  - Manual reconnect handling (the library's own auto-reconnect is
69
131
  disabled) with a configurable delay
70
132
  - Registration timeout with an audit log (`debug.monitorAudit`)
@@ -97,6 +159,9 @@ independent client for its Socket.IO interface.
97
159
  at the wrong moment), a watchdog automatically finalizes the incident
98
160
  once its `ablaufzeit` has passed by more than a grace period
99
161
  (60 seconds), instead of leaving stale "active" data indefinitely.
162
+ - Only ever shows the single most recently active incident; multiple
163
+ concurrently active incidents can currently only be viewed via the
164
+ WAIP-Web instance's own dashboard
100
165
 
101
166
  ### Why a session cookie is needed
102
167
 
@@ -164,6 +229,26 @@ a reliable switch for whether these fields currently hold real live data.
164
229
  The most recently finished incident remains available via
165
230
  `einsatz.json.history10`:
166
231
 
232
+ > **Note:** The adapter always reflects only the single most recently
233
+ > active incident (`einsatz.*` / `einsatz.json.current`) – matching the
234
+ > official WAIP-Web frontend's alarm monitor. WAIP-Web can, in principle,
235
+ > have several incidents active at the same time (e.g. two alerts coming
236
+ > in close together). These states are **not an array of concurrently
237
+ > running incidents** – they get overwritten by each new `io.new_waip`
238
+ > event, so a second incident running in parallel is currently not
239
+ > visible through this adapter. A complete overview of all currently
240
+ > active incidents is, for now, only available via the connected
241
+ > WAIP-Web instance's own dashboard.
242
+
243
+ > **Note:** WAIP-Web's server only fills `einsatznummer`, `objekt`/
244
+ > `objektteil`, `besonderheiten`, `strasse`/`hausnummer`,
245
+ > `einsatzdetails` and the permission flag for **logged-in** clients
246
+ > (`db_user_check_permission_for_waip()` in the server's own
247
+ > `server/waip.js`) - since this adapter connects without a login by
248
+ > design (see [About this adapter](#about-this-adapter)), the server
249
+ > always sends these blank/`false`. They are therefore not exposed as
250
+ > states at all rather than permanently carrying dead values.
251
+
167
252
  | State | Type | Description |
168
253
  | --- | --- | --- |
169
254
  | `alarmAktiv` | boolean | `true` since the last `io.new_waip`, `false` since the last `io.standby` |
@@ -174,15 +259,9 @@ The most recently finished incident remains available via
174
259
  | `stichwort` | string | Alarm keyword |
175
260
  | `ort` | string | Location/town |
176
261
  | `ortsteil` | string | District (if different from `ort`) |
177
- | `strasse` / `hausnummer` | string | Address |
178
- | `objekt` / `objektteil` | string | Building name and part |
179
- | `einsatzdetails` | string | Extra details (only populated for fire/technical-assistance incidents) |
180
- | `besonderheiten` | string | Free-text remarks from the dispatch center |
181
262
  | `zeitstempel` | string (date) | Alarm time |
182
263
  | `ablaufzeit` | string (date) | End of the standby display duration, basis for `restzeit` |
183
- | `einsatznummer` | string | Incident number (if assigned by the server) |
184
264
  | `sondersignal` | number | `1` = special signal (lights & siren), otherwise none |
185
- | `permissions` | string | The registration's permission flag (full access to the detail map yes/no); always stringified (e.g. `"true"`), since the server sends it as a raw boolean |
186
265
  | `latitude` / `longitude` | number | Incident location (normalized from wgs84 fields or GeoJSON centroid) |
187
266
  | `routenGesamt` | number | Number of routes in the current incident |
188
267
  | `rueckmeldungGesamt` | number | Total feedback count for the current incident |
@@ -202,13 +281,13 @@ directly to VIS table widgets (nested structures like a plain
202
281
  `{routen, rueckmeldungen, ...}` object generally aren't rendered by
203
282
  those widgets). `routen`/`rueckmeldungen`/`emAlarmiert`/`emWeitere` only
204
283
  ever hold the *current* incident's data – they are cleared (`[]`) on
205
- `io.standby` and are **not** part of the history. `permissions` inside
206
- `current`/`history10` is stringified the same way as the standalone
207
- `einsatz.permissions` state.
284
+ `io.standby` and are **not** part of the history. As with `einsatz.*`
285
+ above, `current` only ever holds the single most recently active
286
+ incident – see the note in the [`einsatz`](#einsatz) section.
208
287
 
209
288
  | State | Type | Description |
210
289
  | --- | --- | --- |
211
- | `current` | string (JSON array) | Current incident's flat data: the same 19 fields as the individual `einsatz.*` states above (`id` … `permissions`, plus `lat`/`lon`), bundled as one object inside a single-element array (`[]` if no incident is active) – the array wrapper is needed because most table widgets require an array at the root, not a bare object |
290
+ | `current` | string (JSON array) | Current incident's flat data: the same 11 fields as the individual `einsatz.*` states above (`id` … `zeitstempel`, plus `lat`/`lon`), plus `registeredMonitor`/`registeredMonitorName` (the monitor the adapter was registered to at the time), bundled as one object inside a single-element array (`[]` if no incident is active) – the array wrapper is needed because most table widgets require an array at the root, not a bare object |
212
291
  | `history10` | string (JSON array) | Last 10 completed incidents, same shape as `current`, one array entry per incident, written on `io.standby` |
213
292
  | `routen` | string (JSON array) | Routes of the current incident; each entry has `nr_wache`, `name_wache`, `color`, `lat`, `lon` (`position` resolved to flat `lat`/`lon`) |
214
293
  | `rueckmeldungen` | string (JSON array) | Feedback entries of the current incident, as received from the server |
@@ -231,8 +310,8 @@ matters in the moment, so only the most recent one is kept.
231
310
 
232
311
  | State | Type | Description |
233
312
  | --- | --- | --- |
234
- | `lastEvent` | string (JSON) | Last received socket event (name + timestamp), for connection diagnostics |
235
- | `normalizedPosition` | string (JSON) | Result of the geodata normalization for the last `io.new_waip` event, as a flat `{lat, lon}` object (both `null` if no valid position could be derived) |
313
+ | `lastEvent` | string (JSON array) | Last received socket event (name + timestamp), for connection diagnostics; single-element array (`[]` if none yet), for VIS table-widget compatibility |
314
+ | `normalizedPosition` | string (JSON array) | Result of the geodata normalization for the last `io.new_waip` event, as a flat single-element `[{lat, lon}]` array (both `null` if no valid position could be derived; `[]` if no event yet), for VIS table-widget compatibility |
236
315
  | `rawPayloadShort` | string | Preview (500 characters) of the raw, unnormalized `io.new_waip` payload |
237
316
  | `ignoredCount` | number | Count of discarded events (payload explicitly named a different monitor ID) |
238
317
  | `monitorAudit` | string (JSON array) | Chronological log of connect/registration/reconnect events (200 entries) |
@@ -240,8 +319,72 @@ matters in the moment, so only the most recent one is kept.
240
319
  | `lastError` | string | Last error message reported by the server (`io.error`); plain text, not JSON, as the server sends this as a bare string |
241
320
  | `serverVersion` | string | Last reported server instance ID (`io.version`); a change suggests a server restart |
242
321
 
322
+ ## Logging
323
+
324
+ All log text is in English. Repeatable failure conditions (session-cookie
325
+ renewal, WAIP registration, the Socket.IO connection, a wrong-monitor
326
+ event flood) are logged once at `warn` on first occurrence, then at
327
+ `debug` while they persist, and once at `info` on recovery – matching the
328
+ [official ioBroker logging guideline](https://github.com/ioBroker/ioBroker.docs/blob/master/docs/en/dev/adapterdev.md#logging).
329
+
330
+ See **[LOGGING.md](LOGGING.md)** for the full reference of every log
331
+ message the adapter can produce, grouped by level, with its cause and an
332
+ example.
333
+
243
334
  ## Changelog
244
335
 
336
+ ### 0.7.18 (2026-08-22)
337
+
338
+ - Fixed `debug.lastEvent`/`debug.normalizedPosition` to hold a
339
+ single-element JSON array instead of a bare object (matching
340
+ `einsatz.json.current`), for direct VIS table-widget compatibility,
341
+ and to correctly initialize to `[]` instead of `null` on a fresh
342
+ install/restart.
343
+ - Removed `einsatz.einsatznummer`/`.objekt`/`.objektteil`/
344
+ `.besonderheiten`/`.strasse`/`.hausnummer`/`.einsatzdetails`/
345
+ `.permissions` (and the corresponding fields in
346
+ `einsatz.json.current`/`.history10`): confirmed via the WAIP-Web
347
+ server source (`server/waip.js`,
348
+ `db_user_check_permission_for_waip()`) that these fields are only
349
+ ever populated for logged-in clients - since this adapter connects
350
+ anonymously by design, they were always empty/`false`. Removed
351
+ instead of permanently carrying dead states - see the note in the
352
+ [`einsatz`](#einsatz) section.
353
+
354
+ ### 0.7.17 (2026-08-22)
355
+
356
+ - Fixed `cleanupObsoleteObjects()` incorrectly deleting and recreating
357
+ the `einsatz.json` channel on every restart (it wasn't checking
358
+ `obj.type`, so the current channel object was mistaken for a leftover
359
+ state from before the 0.7.15 migration).
360
+ - Fixed a spurious `status.registrationPending` "no existing object"
361
+ warning that could occur if the adapter was stopped before object
362
+ initialization had finished.
363
+ - Reduced WAIP registration from three emits to a single emit - Socket.IO
364
+ already delivers reliably once connected, and the existing registration
365
+ timeout remains as the safety net for the rare case it doesn't confirm.
366
+ - `permissions` inside `einsatz.json.current`/`.history10` is now always
367
+ stringified consistently with the standalone `einsatz.permissions`
368
+ state, and `einsatz.json.current` is wrapped in a single-element array
369
+ (VIS table widgets require an array at the root, not a bare object).
370
+ - Fixed `einsatz.json.history10`/`debug.monitorAudit` staying `null`
371
+ instead of `[]` on a fresh install (they're excluded from the
372
+ per-restart reset to preserve history, which previously also meant
373
+ they were never initialized at all on first install).
374
+ - Added `registeredMonitor`/`registeredMonitorName` fields to
375
+ `einsatz.json.current`/`.history10`.
376
+ - Reworked logging: translated all remaining German log text to
377
+ English; implemented the official first-occurrence-`warn`/
378
+ repeat-`debug`/recovery-`info` pattern for recurring failures (session
379
+ cookie, registration, connection); capped noisy Socket.IO ping/pong
380
+ debug logging; a sustained flood of wrong-monitor events now escalates
381
+ to `warn` instead of staying at `info` indefinitely. See
382
+ [LOGGING.md](LOGGING.md) for the full reference.
383
+ - Documentation: added a table of contents, a practical-use-cases
384
+ section, a known-limitation note (only the single most recently active
385
+ incident is shown - see [`einsatz`](#einsatz)), and enforced the
386
+ changelog's own 5-entry limit.
387
+
245
388
  ### 0.7.16 (2026-08-22)
246
389
 
247
390
  - Fixed two stale-data gaps around incident transitions:
@@ -289,83 +432,6 @@ matters in the moment, so only the most recent one is kept.
289
432
  minor only for security fixes; development: minor allowed too).
290
433
  - No runtime changes.
291
434
 
292
- ### 0.7.13 (2026-08-22)
293
-
294
- - Addressed all remaining `ioBroker.repositories` checker suggestions:
295
- - **[S0065]**/**[S0085]**/**[S0087]**: added devDependencies
296
- `@types/node` and `@tsconfig/node22`, plus a `tsconfig.json` for
297
- editor tooling (no `checkJs`, so this doesn't introduce any new
298
- type-check warnings).
299
- - **[S4036]**: added `.vscode/settings.json` with JSON schemas for
300
- `io-package.json`/`admin/jsonConfig.json`.
301
- - **[S5026]**: added the `release-script-plugin-manual-review`
302
- plugin (adds a confirm-before-commit step to interactive
303
- `npm run release` runs only).
304
- - **[S8913]**: added a Dependabot auto-merge workflow for
305
- patch/minor updates; major version bumps still require manual
306
- review.
307
- - No runtime changes.
308
-
309
- ### 0.7.12 (2026-08-21)
310
-
311
- - Fixed **[E3005]**: `einsatz.permissions` is declared as
312
- `common.type: "string"`, but `setField()` passed raw
313
- booleans/numbers through unchanged (the WAIP server sends this
314
- field as a raw boolean flag), so the stored `val` didn't match the
315
- declared type. `setField()` now looks up the declared type and
316
- always stringifies values for string-typed states, regardless of
317
- the incoming JS type - found by the `ioBroker.repositories` object
318
- structure check.
319
-
320
- ### 0.7.11 (2026-08-21)
321
-
322
- - Fixed **[E3009]** (57 findings): added the missing channel/folder
323
- objects (`status`, `einsatz`, `einsatz.rueckmeldungAnzahl`, `debug`,
324
- `tts`) that ioBroker requires for every state path segment - found
325
- by the `ioBroker.repositories` object structure check.
326
- - Fixed **[E3005]**/**[E1009]**: replaced the unsupported
327
- `common.type: "mixed"` on `einsatz.permissions` (now `string`) and
328
- `status.registrationAccepted` (now split into two booleans:
329
- `registrationAccepted` and the new `registrationPending`).
330
-
331
- ### 0.7.10 (2026-08-21)
332
-
333
- - Fixed **[S9508]**: excluded `CHANGELOG_OLD.md` from the npm package
334
- (removed from `package.json`'s `files` allowlist) - ioBroker shows
335
- the README via a GitHub link, not from the installed npm package, so
336
- the file remains fully readable on GitHub without needing to ship
337
- inside the tarball.
338
-
339
- ### 0.7.9 (2026-08-21)
340
-
341
- - Fixed **[E5025]**/**[E5036]**: installed the missing
342
- `@alcalzone/release-script-plugin-license` dev dependency required
343
- for the `"license"` plugin referenced in `.releaseconfig.json`.
344
-
345
- ### 0.7.8 (2026-08-21)
346
-
347
- - Fixed **[E5018]**: added the missing `.releaseconfig.json` (`plugins:
348
- iobroker, license`) required now that `@alcalzone/release-script` is
349
- a dev dependency - caught by the `ioBroker.repositories` "ADD TO
350
- LATEST" submission check.
351
-
352
- ### 0.7.7 (2026-08-21)
353
-
354
- - Fixed **[E254]**: removed the orphaned `0.7.5` entry from
355
- `common.news` - like `0.7.0` and `0.7.3` before it, that version was
356
- never actually tagged/published to npm (`0.7.4` was followed directly
357
- by `0.7.6`, which is now confirmed live under `latest`).
358
-
359
- ### 0.7.6 (2026-08-21)
360
-
361
- - Fixed **[W6019]** and **[W0062]**: added `@alcalzone/release-script`
362
- and `@alcalzone/release-script-plugin-iobroker` as dev dependencies
363
- (with an `npm run release` script), and split this changelog - the 5
364
- most recent entries stay here, everything older moved to
365
- [CHANGELOG_OLD.md](CHANGELOG_OLD.md). Our existing manual
366
- version-bump/tag workflow (see below) is unchanged; the tool is
367
- available but not actively used for releasing yet.
368
-
369
435
  Older entries have moved to [CHANGELOG_OLD.md](CHANGELOG_OLD.md).
370
436
 
371
437
  ## License