iobroker.waip-web 0.7.34 → 0.7.36

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
@@ -104,10 +104,11 @@ Rettungsdienst-Wache:
104
104
  ansetzen (oder die URL direkt abspielen), um den Einsatz über
105
105
  Gebäudelautsprecher anzusagen, sobald `io.playtts` feuert – hilfreich,
106
106
  wenn nicht alle Mitglieder gerade auf einen Bildschirm schauen.
107
- - **Live-Übersicht der Rückmeldungen.** Die `einsatz.rueckmeldungAnzahl.*`
108
- Zähler (pro Rolle: EK/GF/ZF/VF, pro Zusatzfunktion: AGT/FZF/MA/MED)
109
- aktualisieren sich in Echtzeit, sobald Einsatzkräfte per App
110
- zurückmelden – als Gauge- oder Zahlen-Widget gebunden ergibt das eine
107
+ - **Live-Übersicht der Rückmeldungen.** Die `einsatz.rueckmeldungen.*`
108
+ Zähler (`rollen.ek`/`.gf`/`.zf`/`.vf` pro Rolle, `funktionen.agt`/`.fzf`/
109
+ `.ma`/`.med` pro Zusatzfunktion) aktualisieren sich in Echtzeit, sobald
110
+ Einsatzkräfte per App zurückmelden – als Gauge- oder Zahlen-Widget
111
+ gebunden ergibt das eine
111
112
  Übersicht auf einen Blick, wer bereits kommt.
112
113
  - **Nachbereitung/Statistik.** `einsatz.json.history10` hält die letzten
113
114
  10 abgeschlossenen Einsätze als flache Tabelle vor – an eine zweite
@@ -453,21 +454,21 @@ stehen. Der zuletzt abgeschlossene Einsatz bleibt trotzdem über
453
454
  | `beschreibung` | string | Beschreibung zu `stichwort`, lokal ermittelt (wird nicht vom Server gesendet) - siehe [Rettungsdienst](#rettungsdienst)/[Stichwort-Stammdaten](#stichwort-stammdaten) unten. `null` falls nichts passte |
454
455
  | `ort` | string | Ort |
455
456
  | `ortsteil` | string | Ortsteil (falls abweichend vom Ort) |
456
- | `zeitstempel` | string (date) | Alarmzeit |
457
+ | `alarmierungszeit` | string (date) | Alarmzeit |
457
458
  | `ablaufzeit` | string (date) | Ende der Standby-Anzeigedauer, Basis für `restzeit` |
458
459
  | `sondersignal` | number | `1` = Sondersignal, sonst kein Sondersignal |
459
460
  | `latitude` / `longitude` | number | Position des Einsatzortes (normalisiert aus wgs84-Feldern oder GeoJSON-Mittelpunkt) |
460
461
  | `kartenbildPfad` | string | Pfad zum zuletzt erzeugten Einsatzkarten-Bild (PNG) - siehe [Einsatzkarte](#einsatzkarte). Leer bis das Bild für den aktuellen Einsatz fertig ist; wird außerdem zu Beginn eines neuen Einsatzes, bei einem Fehlschlag der Erzeugung oder falls das OSM-Timeout überschritten wird geleert (bzw. bleibt leer), sowie - wie die übrigen Felder oben - bei `io.standby`. Die zugrundeliegende Bild-Datei selbst wird beim Leeren des States nicht gelöscht (nur das 10er-Rotationslimit entfernt Dateien, siehe [Einsatzkarte](#einsatzkarte)) |
461
462
  | `routenGesamt` | number | Anzahl Routen im aktuellen Einsatz |
462
- | `rueckmeldungGesamt` | number | Rückmeldungen gesamt im aktuellen Einsatz |
463
- | `rueckmeldungAnzahl.ek` | number | Anzahl Rückmeldungen als Einsatzkraft |
464
- | `rueckmeldungAnzahl.gf` | number | Anzahl Rückmeldungen als Gruppenführer |
465
- | `rueckmeldungAnzahl.zf` | number | Anzahl Rückmeldungen als Zugführer |
466
- | `rueckmeldungAnzahl.vf` | number | Anzahl Rückmeldungen als Verbandsführer |
467
- | `rueckmeldungAnzahl.agt` | number | Anzahl Rückmeldungen mit Atemschutz-Befähigung |
468
- | `rueckmeldungAnzahl.fzf` | number | Anzahl Rückmeldungen als Fahrzeugführer |
469
- | `rueckmeldungAnzahl.ma` | number | Anzahl Rückmeldungen als Maschinist |
470
- | `rueckmeldungAnzahl.med` | number | Anzahl Rückmeldungen mit medizinischer Befähigung |
463
+ | `rueckmeldungenGesamt` | number | Rückmeldungen gesamt im aktuellen Einsatz |
464
+ | `rueckmeldungen.rollen.ek` | number | Anzahl Rückmeldungen als Einsatzkraft |
465
+ | `rueckmeldungen.rollen.gf` | number | Anzahl Rückmeldungen als Gruppenführer |
466
+ | `rueckmeldungen.rollen.zf` | number | Anzahl Rückmeldungen als Zugführer |
467
+ | `rueckmeldungen.rollen.vf` | number | Anzahl Rückmeldungen als Verbandsführer |
468
+ | `rueckmeldungen.funktionen.agt` | number | Anzahl Rückmeldungen mit Atemschutz-Befähigung |
469
+ | `rueckmeldungen.funktionen.fzf` | number | Anzahl Rückmeldungen als Fahrzeugführer |
470
+ | `rueckmeldungen.funktionen.ma` | number | Anzahl Rückmeldungen als Maschinist |
471
+ | `rueckmeldungen.funktionen.med` | number | Anzahl Rückmeldungen mit medizinischer Befähigung |
471
472
 
472
473
  ### einsatz.json
473
474
 
@@ -483,7 +484,7 @@ Abschnitt [`einsatz`](#einsatz).
483
484
 
484
485
  | State | Typ | Beschreibung |
485
486
  | --- | --- | --- |
486
- | `current` | string (JSON-Array) | Flache Daten des aktuellen Einsatzes: dieselben 12 Felder wie die einzelnen `einsatz.*`-States oben (`id` … `zeitstempel`, plus `beschreibung`, `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 |
487
+ | `current` | string (JSON-Array) | Flache Daten des aktuellen Einsatzes: dieselben 12 Felder wie die einzelnen `einsatz.*`-States oben (`id` … `sondersignal`, plus `beschreibung`, `alarmierungszeit`, `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 |
487
488
  | `history10` | string (JSON-Array) | Letzte 10 abgeschlossenen Einsätze, gleiches Schema wie `current`, ein Array-Eintrag pro Einsatz, geschrieben bei `io.standby` |
488
489
  | `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) |
489
490
  | `rueckmeldungen` | string (JSON-Array) | Rückmeldungen des aktuellen Einsatzes, wie vom Server empfangen |
package/README.md CHANGED
@@ -111,10 +111,11 @@ adapter provides – typical use in a fire station/EMS environment:
111
111
  automation at it (or just play the URL directly) to have the incident
112
112
  announced over building speakers the moment `io.playtts` fires –
113
113
  useful where members aren't all looking at a screen.
114
- - **Live headcount / feedback board.** The `einsatz.rueckmeldungAnzahl.*`
115
- counters (per role: EK/GF/ZF/VF, per qualification: AGT/FZF/MA/MED)
116
- update in real time as responders confirm via the app – bind them to
117
- gauge or number widgets for an at-a-glance "who's coming" overview
114
+ - **Live headcount / feedback board.** The `einsatz.rueckmeldungen.*`
115
+ counters (`rollen.ek`/`.gf`/`.zf`/`.vf` per role, `funktionen.agt`/`.fzf`/
116
+ `.ma`/`.med` per qualification) update in real time as responders
117
+ confirm via the app – bind them to gauge or number widgets for an
118
+ at-a-glance "who's coming" overview
118
119
  during the response.
119
120
  - **Post-incident review / statistics.** `einsatz.json.history10` keeps
120
121
  the last 10 completed incidents as a flat table – bind it to a second
@@ -438,21 +439,21 @@ The most recently finished incident remains available via
438
439
  | `beschreibung` | string | Description for `stichwort`, resolved locally (not sent by the server) - see [Rescue service](#rescue-service)/[Keyword descriptions](#keyword-descriptions) below. `null` if nothing matched |
439
440
  | `ort` | string | Location/town |
440
441
  | `ortsteil` | string | District (if different from `ort`) |
441
- | `zeitstempel` | string (date) | Alarm time |
442
+ | `alarmierungszeit` | string (date) | Alarm time |
442
443
  | `ablaufzeit` | string (date) | End of the standby display duration, basis for `restzeit` |
443
444
  | `sondersignal` | number | `1` = special signal (lights & siren), otherwise none |
444
445
  | `latitude` / `longitude` | number | Incident location (normalized from wgs84 fields or GeoJSON centroid) |
445
446
  | `kartenbildPfad` | string | Path to the most recently generated incident map image (PNG) - see [Incident map image](#incident-map-image). Empty until the first image for the current incident is ready; also cleared (stays empty) at the start of a new incident, if generation fails, or if it doesn't finish within the OSM timeout, and - like the other fields above - on `io.standby`. The underlying image file itself is not deleted when the state is cleared (only the 10-image retention limit removes files, see [Incident map image](#incident-map-image)) |
446
447
  | `routenGesamt` | number | Number of routes in the current incident |
447
- | `rueckmeldungGesamt` | number | Total feedback count for the current incident |
448
- | `rueckmeldungAnzahl.ek` | number | Feedback count as team member ("Einsatzkraft") |
449
- | `rueckmeldungAnzahl.gf` | number | Feedback count as crew leader ("Gruppenführer") |
450
- | `rueckmeldungAnzahl.zf` | number | Feedback count as division chief ("Zugführer") |
451
- | `rueckmeldungAnzahl.vf` | number | Feedback count as group commander ("Verbandsführer") |
452
- | `rueckmeldungAnzahl.agt` | number | Feedback count with breathing-apparatus qualification ("Atemschutzgeräteträger") |
453
- | `rueckmeldungAnzahl.fzf` | number | Feedback count as vehicle commander ("Fahrzeugführer") |
454
- | `rueckmeldungAnzahl.ma` | number | Feedback count as driver/operator ("Maschinist") |
455
- | `rueckmeldungAnzahl.med` | number | Feedback count with a medical qualification |
448
+ | `rueckmeldungenGesamt` | number | Total feedback count for the current incident |
449
+ | `rueckmeldungen.rollen.ek` | number | Feedback count as team member ("Einsatzkraft") |
450
+ | `rueckmeldungen.rollen.gf` | number | Feedback count as crew leader ("Gruppenführer") |
451
+ | `rueckmeldungen.rollen.zf` | number | Feedback count as division chief ("Zugführer") |
452
+ | `rueckmeldungen.rollen.vf` | number | Feedback count as group commander ("Verbandsführer") |
453
+ | `rueckmeldungen.funktionen.agt` | number | Feedback count with breathing-apparatus qualification ("Atemschutzgeräteträger") |
454
+ | `rueckmeldungen.funktionen.fzf` | number | Feedback count as vehicle commander ("Fahrzeugführer") |
455
+ | `rueckmeldungen.funktionen.ma` | number | Feedback count as driver/operator ("Maschinist") |
456
+ | `rueckmeldungen.funktionen.med` | number | Feedback count with a medical qualification |
456
457
 
457
458
  ### einsatz.json
458
459
 
@@ -467,7 +468,7 @@ incident – see the note in the [`einsatz`](#einsatz) section.
467
468
 
468
469
  | State | Type | Description |
469
470
  | --- | --- | --- |
470
- | `current` | string (JSON array) | Current incident's flat data: the same 12 fields as the individual `einsatz.*` states above (`id` … `zeitstempel`, plus `beschreibung`, `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 |
471
+ | `current` | string (JSON array) | Current incident's flat data: the same 12 fields as the individual `einsatz.*` states above (`id` … `sondersignal`, plus `beschreibung`, `alarmierungszeit`, `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 |
471
472
  | `history10` | string (JSON array) | Last 10 completed incidents, same shape as `current`, one array entry per incident, written on `io.standby` |
472
473
  | `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`) |
473
474
  | `rueckmeldungen` | string (JSON array) | Feedback entries of the current incident, as received from the server |
@@ -513,6 +514,28 @@ example.
513
514
 
514
515
  ## Changelog
515
516
 
517
+ ### 0.7.36 (2026-08-25)
518
+
519
+ - Object structure change: `einsatz.rueckmeldungAnzahl` is now
520
+ **`einsatz.rueckmeldungen`** (the `rollen.*`/`funktionen.*`
521
+ sub-channels are unchanged), `einsatz.rueckmeldungGesamt` is now
522
+ **`einsatz.rueckmeldungenGesamt`**, and `einsatz.zeitstempel` is now
523
+ **`einsatz.alarmierungszeit`**. Old objects (including now-orphaned
524
+ channel/folder objects, not just states) are removed automatically
525
+ on upgrade; scripts/VIS bindings referencing the old paths need to
526
+ be updated - see [einsatz](#einsatz).
527
+
528
+ ### 0.7.35 (2026-08-24)
529
+
530
+ - Object structure change: the eight feedback counters under
531
+ `einsatz.rueckmeldungAnzahl` are now grouped into two sub-channels -
532
+ **rollen** (`ek`/`gf`/`zf`/`vf`, by role) and **funktionen**
533
+ (`agt`/`fzf`/`ma`/`med`, by qualification) - instead of sitting flat
534
+ next to each other. The old flat states are removed automatically on
535
+ upgrade; scripts/VIS bindings referencing the old paths need to be
536
+ updated to the new `einsatz.rueckmeldungAnzahl.rollen.*`/
537
+ `.funktionen.*` paths - see [einsatz](#einsatz).
538
+
516
539
  ### 0.7.34 (2026-08-24)
517
540
 
518
541
  - [Incident map image](#incident-map-image): fixed the help texts for
@@ -546,47 +569,6 @@ example.
546
569
  caught - harmless, but noisy. Object initialization now stops
547
570
  cleanly and logs a single warning instead.
548
571
 
549
- ### 0.7.31 (2026-08-24)
550
-
551
- - Fixed two `einsatz.kartenbildPfad` timing/staleness issues:
552
- - Alarm processing now **waits** for the
553
- [incident map image](#incident-map-image) to finish before
554
- continuing, instead of generating it in the background - so
555
- `einsatz.kartenbildPfad` and `einsatz.alarmAktiv` become available
556
- together. The wait is capped by a new configurable **OSM timeout**
557
- (1-60s, default 10s): if the image isn't ready in time, a warning
558
- is logged and `kartenbildPfad` stays empty for that incident
559
- instead of blocking alarm processing indefinitely.
560
- - `einsatz.kartenbildPfad` is now reset immediately when a new
561
- incident starts, instead of possibly still showing a previous
562
- incident's stale image path (e.g. when the new incident has no
563
- coordinates, or the map image feature just got disabled).
564
-
565
- ### 0.7.30 (2026-08-24)
566
-
567
- - [Incident map image](#incident-map-image): new **Show incident-area
568
- polygon** checkbox (on by default) - uncheck it to always show the
569
- centered marker dot instead, even when the server sends a polygon.
570
- The margin kept around the polygon when auto-zooming to fit it was
571
- also reduced by 30%, so the area fills more of the image. Default
572
- zoom level raised from 16 to 19, default outline thickness from 3 to
573
- 4 px.
574
- - `einsatz.kartenbildPfad` is now cleared on `io.standby` like the
575
- other `einsatz.*` fields (previously kept, matching
576
- `einsatz.tts.last`'s pattern) - the image file itself is unaffected,
577
- only the 10-image retention limit ever deletes files.
578
- - Documented that this adapter's own data directory (generated map
579
- images) is only removed on instance/adapter deletion if "Also
580
- delete instance data" is checked in Admin's deletion dialog - a
581
- native js-controller/Admin feature (unchecked by default), not
582
- something this adapter's code controls.
583
- - Removed "Unofficial"/"Inoffiziell" from both READMEs' wording; the
584
- disclaimer about having no connection to the WAIP-Web project/
585
- Robert-112 itself is unchanged, just reworded without that word.
586
- - This Changelog section now shows only the 5 most recent versions -
587
- older entries move to [CHANGELOG_OLD.md](CHANGELOG_OLD.md) on every
588
- release.
589
-
590
572
  Older entries have moved to [CHANGELOG_OLD.md](CHANGELOG_OLD.md) - this
591
573
  section shows only the 5 most recent versions.
592
574
 
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "waip-web",
4
- "version": "0.7.34",
4
+ "version": "0.7.36",
5
5
  "news": {
6
+ "0.7.36": {
7
+ "en": "Object structure change: einsatz.rueckmeldungAnzahl is now einsatz.rueckmeldungen (rollen.*/funktionen.* sub-channels unchanged), einsatz.rueckmeldungGesamt is now einsatz.rueckmeldungenGesamt, and einsatz.zeitstempel is now einsatz.alarmierungszeit. Old objects are automatically removed on upgrade (including now-orphaned channel/folder objects, not just states); scripts/VIS bindings referencing the old paths need to be updated.",
8
+ "de": "Objektstruktur geändert: einsatz.rueckmeldungAnzahl heißt jetzt einsatz.rueckmeldungen (Unter-Kanäle rollen.*/funktionen.* unverändert), einsatz.rueckmeldungGesamt heißt jetzt einsatz.rueckmeldungenGesamt, und einsatz.zeitstempel heißt jetzt einsatz.alarmierungszeit. Alte Objekte werden beim Update automatisch entfernt (auch jetzt verwaiste Kanal-/Ordner-Objekte, nicht nur States); Skripte/VIS-Bindings, die die alten Pfade nutzen, müssen angepasst werden.",
9
+ "es": "Cambio en la estructura de objetos: einsatz.rueckmeldungAnzahl ahora es einsatz.rueckmeldungen (los subcanales rollen.*/funktionen.* no cambian), einsatz.rueckmeldungGesamt ahora es einsatz.rueckmeldungenGesamt, y einsatz.zeitstempel ahora es einsatz.alarmierungszeit. Los objetos antiguos se eliminan automáticamente al actualizar (incluidos los objetos de canal/carpeta ahora huérfanos, no solo los estados); los scripts/vinculaciones de VIS que hagan referencia a las rutas antiguas deben actualizarse.",
10
+ "fr": "Changement de la structure des objets : einsatz.rueckmeldungAnzahl s'appelle désormais einsatz.rueckmeldungen (les sous-canaux rollen.*/funktionen.* restent inchangés), einsatz.rueckmeldungGesamt s'appelle désormais einsatz.rueckmeldungenGesamt, et einsatz.zeitstempel s'appelle désormais einsatz.alarmierungszeit. Les anciens objets sont automatiquement supprimés lors de la mise à jour (y compris les objets de canal/dossier désormais orphelins, pas seulement les états) ; les scripts/liaisons VIS référençant les anciens chemins doivent être mis à jour.",
11
+ "it": "Modifica della struttura degli oggetti: einsatz.rueckmeldungAnzahl ora si chiama einsatz.rueckmeldungen (i sottocanali rollen.*/funktionen.* restano invariati), einsatz.rueckmeldungGesamt ora si chiama einsatz.rueckmeldungenGesamt, e einsatz.zeitstempel ora si chiama einsatz.alarmierungszeit. I vecchi oggetti vengono rimossi automaticamente durante l'aggiornamento (inclusi gli oggetti canale/cartella ora orfani, non solo gli stati); script/binding VIS che fanno riferimento ai vecchi percorsi devono essere aggiornati.",
12
+ "nl": "Wijziging in de objectstructuur: einsatz.rueckmeldungAnzahl heet nu einsatz.rueckmeldungen (subkanalen rollen.*/funktionen.* ongewijzigd), einsatz.rueckmeldungGesamt heet nu einsatz.rueckmeldungenGesamt, en einsatz.zeitstempel heet nu einsatz.alarmierungszeit. Oude objecten worden bij een update automatisch verwijderd (ook nu wees geworden kanaal-/mapobjecten, niet alleen states); scripts/VIS-bindingen die naar de oude paden verwijzen, moeten worden aangepast.",
13
+ "pl": "Zmiana struktury obiektów: einsatz.rueckmeldungAnzahl nazywa się teraz einsatz.rueckmeldungen (podkanały rollen.*/funktionen.* bez zmian), einsatz.rueckmeldungGesamt nazywa się teraz einsatz.rueckmeldungenGesamt, a einsatz.zeitstempel nazywa się teraz einsatz.alarmierungszeit. Stare obiekty są automatycznie usuwane podczas aktualizacji (w tym osierocone teraz obiekty kanałów/folderów, nie tylko stany); skrypty/powiązania VIS odwołujące się do starych ścieżek należy zaktualizować.",
14
+ "pt": "Alteração na estrutura de objetos: einsatz.rueckmeldungAnzahl agora chama-se einsatz.rueckmeldungen (subcanais rollen.*/funktionen.* inalterados), einsatz.rueckmeldungGesamt agora chama-se einsatz.rueckmeldungenGesamt, e einsatz.zeitstempel agora chama-se einsatz.alarmierungszeit. Os objetos antigos são removidos automaticamente na atualização (incluindo objetos de canal/pasta agora órfãos, não apenas estados); scripts/vinculações do VIS que referenciam os caminhos antigos devem ser atualizados.",
15
+ "ru": "Изменение структуры объектов: einsatz.rueckmeldungAnzahl теперь называется einsatz.rueckmeldungen (подканалы rollen.*/funktionen.* без изменений), einsatz.rueckmeldungGesamt теперь называется einsatz.rueckmeldungenGesamt, а einsatz.zeitstempel теперь называется einsatz.alarmierungszeit. Старые объекты автоматически удаляются при обновлении (включая ставшие теперь бесхозными объекты каналов/папок, а не только состояния); скрипты/привязки VIS, ссылающиеся на старые пути, необходимо обновить.",
16
+ "uk": "Зміна структури об'єктів: einsatz.rueckmeldungAnzahl тепер називається einsatz.rueckmeldungen (підканали rollen.*/funktionen.* без змін), einsatz.rueckmeldungGesamt тепер називається einsatz.rueckmeldungenGesamt, а einsatz.zeitstempel тепер називається einsatz.alarmierungszeit. Старі об'єкти автоматично видаляються під час оновлення (включно з тепер осиротілими об'єктами каналів/папок, а не лише станами); скрипти/прив'язки VIS, що посилаються на старі шляхи, потрібно оновити.",
17
+ "zh-cn": "对象结构变更:einsatz.rueckmeldungAnzahl 现更名为 einsatz.rueckmeldungen(子通道 rollen.*/funktionen.* 保持不变),einsatz.rueckmeldungGesamt 现更名为 einsatz.rueckmeldungenGesamt,einsatz.zeitstempel 现更名为 einsatz.alarmierungszeit。旧对象会在更新时自动移除(包括现已成为孤立对象的通道/文件夹对象,不仅仅是状态);引用旧路径的脚本/VIS 绑定需要更新。"
18
+ },
19
+ "0.7.35": {
20
+ "en": "Object structure change: the eight feedback counters under einsatz.rueckmeldungAnzahl are now grouped into two sub-channels - rollen (ek/gf/zf/vf, by role) and funktionen (agt/fzf/ma/med, by qualification) - instead of sitting flat next to each other. The old flat states are automatically removed on upgrade; scripts/VIS bindings referencing the old paths need to be updated to the new einsatz.rueckmeldungAnzahl.rollen.*/funktionen.* paths.",
21
+ "de": "Objektstruktur geändert: Die acht Rückmeldungs-Zähler unter einsatz.rueckmeldungAnzahl sind jetzt in zwei Unter-Kanälen gruppiert - rollen (ek/gf/zf/vf, nach Rolle) und funktionen (agt/fzf/ma/med, nach Zusatzfunktion) - statt flach nebeneinander zu liegen. Die alten flachen States werden beim Update automatisch entfernt; Skripte/VIS-Bindings, die die alten Pfade nutzen, müssen auf die neuen Pfade einsatz.rueckmeldungAnzahl.rollen.*/funktionen.* angepasst werden.",
22
+ "es": "Cambio en la estructura de objetos: los ocho contadores de confirmaciones bajo einsatz.rueckmeldungAnzahl ahora están agrupados en dos subcanales - rollen (ek/gf/zf/vf, por rol) y funktionen (agt/fzf/ma/med, por cualificación) - en lugar de estar planos uno junto al otro. Los antiguos estados planos se eliminan automáticamente al actualizar; los scripts/vinculaciones de VIS que hagan referencia a las rutas antiguas deben actualizarse a las nuevas rutas einsatz.rueckmeldungAnzahl.rollen.*/funktionen.*.",
23
+ "fr": "Changement de la structure des objets : les huit compteurs de confirmations sous einsatz.rueckmeldungAnzahl sont désormais regroupés en deux sous-canaux - rollen (ek/gf/zf/vf, par rôle) et funktionen (agt/fzf/ma/med, par qualification) - au lieu d'être placés à plat les uns à côté des autres. Les anciens états à plat sont automatiquement supprimés lors de la mise à jour ; les scripts/liaisons VIS référençant les anciens chemins doivent être mis à jour vers les nouveaux chemins einsatz.rueckmeldungAnzahl.rollen.*/funktionen.*.",
24
+ "it": "Modifica della struttura degli oggetti: gli otto contatori di conferme sotto einsatz.rueckmeldungAnzahl sono ora raggruppati in due sottocanali - rollen (ek/gf/zf/vf, per ruolo) e funktionen (agt/fzf/ma/med, per qualifica) - invece di trovarsi allo stesso livello uno accanto all'altro. I vecchi stati piatti vengono rimossi automaticamente durante l'aggiornamento; script/binding VIS che fanno riferimento ai vecchi percorsi devono essere aggiornati ai nuovi percorsi einsatz.rueckmeldungAnzahl.rollen.*/funktionen.*.",
25
+ "nl": "Wijziging in de objectstructuur: de acht terugmeldingstellers onder einsatz.rueckmeldungAnzahl zijn nu gegroepeerd in twee subkanalen - rollen (ek/gf/zf/vf, per rol) en funktionen (agt/fzf/ma/med, per kwalificatie) - in plaats van plat naast elkaar te staan. De oude platte states worden bij een update automatisch verwijderd; scripts/VIS-bindingen die naar de oude paden verwijzen, moeten worden aangepast naar de nieuwe paden einsatz.rueckmeldungAnzahl.rollen.*/funktionen.*.",
26
+ "pl": "Zmiana struktury obiektów: osiem liczników potwierdzeń pod einsatz.rueckmeldungAnzahl jest teraz zgrupowanych w dwóch podkanałach - rollen (ek/gf/zf/vf, według roli) i funktionen (agt/fzf/ma/med, według kwalifikacji) - zamiast leżeć płasko obok siebie. Stare płaskie stany są automatycznie usuwane podczas aktualizacji; skrypty/powiązania VIS odwołujące się do starych ścieżek należy zaktualizować do nowych ścieżek einsatz.rueckmeldungAnzahl.rollen.*/funktionen.*.",
27
+ "pt": "Alteração na estrutura de objetos: os oito contadores de confirmações em einsatz.rueckmeldungAnzahl agora estão agrupados em dois subcanais - rollen (ek/gf/zf/vf, por função) e funktionen (agt/fzf/ma/med, por qualificação) - em vez de estarem lado a lado de forma plana. Os estados antigos planos são removidos automaticamente na atualização; scripts/vinculações do VIS que referenciam os caminhos antigos devem ser atualizados para os novos caminhos einsatz.rueckmeldungAnzahl.rollen.*/funktionen.*.",
28
+ "ru": "Изменение структуры объектов: восемь счётчиков подтверждений в einsatz.rueckmeldungAnzahl теперь сгруппированы в два подканала - rollen (ek/gf/zf/vf, по роли) и funktionen (agt/fzf/ma/med, по квалификации) - вместо того чтобы находиться плоско рядом друг с другом. Старые плоские состояния автоматически удаляются при обновлении; скрипты/привязки VIS, ссылающиеся на старые пути, необходимо обновить на новые пути einsatz.rueckmeldungAnzahl.rollen.*/funktionen.*.",
29
+ "uk": "Зміна структури об'єктів: вісім лічильників підтверджень у einsatz.rueckmeldungAnzahl тепер згруповано у два підканали - rollen (ek/gf/zf/vf, за роллю) і funktionen (agt/fzf/ma/med, за кваліфікацією) - замість того, щоб лежати пласко поруч одне з одним. Старі пласкі стани автоматично видаляються під час оновлення; скрипти/прив'язки VIS, що посилаються на старі шляхи, потрібно оновити на нові шляхи einsatz.rueckmeldungAnzahl.rollen.*/funktionen.*.",
30
+ "zh-cn": "对象结构变更:einsatz.rueckmeldungAnzahl 下的八个反馈计数器现已分组到两个子通道 - rollen(按角色分类:ek/gf/zf/vf)和 funktionen(按资质分类:agt/fzf/ma/med)- 而不再是平铺排列。旧的扁平状态会在更新时自动移除;引用旧路径的脚本/VIS 绑定需要更新为新路径 einsatz.rueckmeldungAnzahl.rollen.*/funktionen.*。"
31
+ },
6
32
  "0.7.34": {
7
33
  "en": "Incident map image tab: fixed help texts for Zoom level, Marker & outline color, Image width/height that referenced \"both display modes below\" and no longer made sense after the previous release moved those fields above the display-mode checkbox; the Zoom level text was also considerably shortened.",
8
34
  "de": "Reiter Einsatzkarte: Hilfetexte für Zoomstufe, Marker- & Umrissfarbe sowie Bildbreite/-höhe korrigiert, die sich auf \"beide Darstellungsarten unten\" bezogen und seit der Feldumsortierung im letzten Release keinen Sinn mehr ergaben; der Zoomstufe-Text wurde zudem deutlich gekürzt.",
@@ -67,32 +93,6 @@
67
93
  "ru": "Новый флажок \"Показывать полигон зоны вызова\" для изображения карты вызова (по умолчанию включён, можно переключить на центрированную точку); отступ автоматического масштабирования вокруг полигона уменьшен на 30%, масштаб по умолчанию увеличен до 19, толщина контура по умолчанию до 4px. einsatz.kartenbildPfad теперь очищается при io.standby, как и другие поля. Задокументирована опция Admin \"удалить данные экземпляра\" для удаления сгенерированных изображений карты при удалении. Из обоих README удалено слово \"Unofficial\". В журнале изменений теперь отображаются только 5 последних версий.",
68
94
  "uk": "Новий прапорець \"Показувати полігон зони виклику\" для зображення карти виклику (типово увімкнено, можна перемкнути на центровану точку); відступ автоматичного масштабування навколо полігона зменшено на 30%, типовий масштаб збільшено до 19, типову товщину контуру до 4px. einsatz.kartenbildPfad тепер очищається при io.standby, як і інші поля. Задокументовано опцію Admin \"видалити дані екземпляра\" для видалення згенерованих зображень карти при видаленні. З обох README видалено слово \"Unofficial\". Журнал змін тепер показує лише 5 останніх версій.",
69
95
  "zh-cn": "为事件地图图像新增\"显示事件区域多边形\"复选框(默认启用,可切换为居中圆点);多边形周围自动缩放适配的边距缩小了30%,默认缩放级别提高到19,默认轮廓粗细提高到4px。einsatz.kartenbildPfad 现在会像其他字段一样在 io.standby 时清空。已记录 Admin 中用于卸载时删除生成的地图图像的\"删除实例数据\"选项。已从两个 README 中删除\"Unofficial\"一词。更新日志现在仅显示最近的5个版本。"
70
- },
71
- "0.7.29": {
72
- "en": "Incident map image now draws the actual incident area WAIP-Web sends (usually a circle polygon), not just a marker dot at its center - falls back to the dot if no polygon is available. Rescue-service keyword decoding now defaults to on for new installations (previously off), matching the rescue-service processing checkbox. Trimmed a redundant justification sentence from both checkboxes' descriptions. The incident area now also always stays fully visible - the adapter automatically zooms out past the configured zoom level if needed, instead of clipping it at the image edge. Outline color and thickness are now configurable too.",
73
- "de": "Die Einsatzkarte zeichnet jetzt das tatsächliche vom WAIP-Web gesendete Einsatzgebiet (meist ein kreisförmiges Polygon) statt nur eine Punkt-Markierung in dessen Mitte - fällt auf den Punkt zurück, falls kein Polygon vorliegt. Die Rettungsdienst-Stichwort-Dekodierung ist bei Neuinstallationen jetzt standardmäßig aktiviert (vorher deaktiviert), passend zur Checkbox für die Rettungsdienst-Verarbeitung. Ein redundanter Begründungssatz wurde aus beiden Checkbox-Beschreibungen entfernt. Das Einsatzgebiet bleibt jetzt außerdem immer vollständig sichtbar - der Adapter zoomt bei Bedarf automatisch über die konfigurierte Zoomstufe hinaus heraus, statt es am Bildrand abzuschneiden. Umrissfarbe und -stärke sind jetzt ebenfalls konfigurierbar.",
74
- "es": "La imagen de mapa del incidente ahora dibuja el área real del incidente que envía WAIP-Web (normalmente un polígono circular), no solo un punto marcador en su centro - recurre al punto si no hay ningún polígono disponible. La decodificación de palabras clave del servicio de rescate ahora está activada por defecto para nuevas instalaciones (antes desactivada), igual que la casilla de procesamiento del servicio de rescate. Se eliminó una frase de justificación redundante de las descripciones de ambas casillas. El área del incidente ahora también permanece siempre completamente visible - el adaptador aleja automáticamente el zoom más allá del nivel configurado si es necesario, en lugar de recortarla en el borde de la imagen. El color y el grosor del contorno ahora también son configurables.",
75
- "fr": "L'image de carte de l'incident dessine désormais la véritable zone d'intervention envoyée par WAIP-Web (généralement un polygone circulaire), et non plus seulement un point marqueur en son centre - revient au point si aucun polygone n'est disponible. Le décodage des mots-clés du service de secours est désormais activé par défaut pour les nouvelles installations (auparavant désactivé), comme la case à cocher de traitement du service de secours. Une phrase de justification redondante a été supprimée des descriptions des deux cases à cocher. La zone d'intervention reste désormais aussi toujours entièrement visible - l'adaptateur dézoome automatiquement au-delà du niveau configuré si nécessaire, plutôt que de la rogner au bord de l'image. La couleur et l'épaisseur du contour sont désormais également configurables.",
76
- "it": "L'immagine della mappa dell'incidente ora disegna l'area effettiva dell'incidente inviata da WAIP-Web (di solito un poligono circolare), non solo un punto marcatore al centro - torna al punto se non è disponibile alcun poligono. La decodifica delle parole chiave del servizio di soccorso è ora attiva per impostazione predefinita per le nuove installazioni (prima disattivata), come la casella di elaborazione del servizio di soccorso. È stata rimossa una frase di giustificazione ridondante dalle descrizioni di entrambe le caselle. Ora l'area dell'incidente rimane sempre completamente visibile - l'adattatore riduce automaticamente lo zoom oltre il livello configurato se necessario, invece di ritagliarla al bordo dell'immagine. Anche il colore e lo spessore del contorno sono ora configurabili.",
77
- "nl": "De incidentkaartafbeelding tekent nu het daadwerkelijke incidentgebied dat WAIP-Web verzendt (meestal een cirkelvormige polygoon), niet alleen een puntmarkering in het midden - valt terug op de stip als er geen polygoon beschikbaar is. Het decoderen van reddingsdienst-trefwoorden staat nu standaard aan bij nieuwe installaties (voorheen uit), net als het selectievakje voor reddingsdienstverwerking. Een overbodige verantwoordingszin is uit beide selectievakjes-beschrijvingen verwijderd. Het incidentgebied blijft nu ook altijd volledig zichtbaar - de adapter zoomt indien nodig automatisch verder uit dan het ingestelde zoomniveau, in plaats van het aan de rand van de afbeelding af te snijden. Contourkleur en -dikte zijn nu ook instelbaar.",
78
- "pl": "Obraz mapy zdarzenia rysuje teraz rzeczywisty obszar zdarzenia wysyłany przez WAIP-Web (zwykle poligon kołowy), a nie tylko znacznik punktowy w jego środku - wraca do punktu, jeśli poligon nie jest dostępny. Dekodowanie słów kluczowych pogotowia ratunkowego jest teraz domyślnie włączone dla nowych instalacji (wcześniej wyłączone), tak jak pole wyboru przetwarzania ratownictwa medycznego. Usunięto zbędne zdanie uzasadniające z opisów obu pól wyboru. Obszar zdarzenia pozostaje teraz zawsze w pełni widoczny - adapter automatycznie pomniejsza powiększenie poza skonfigurowany poziom, jeśli to konieczne, zamiast przycinać go na krawędzi obrazu. Kolor i grubość konturu są teraz również konfigurowalne.",
79
- "pt": "A imagem de mapa da ocorrência agora desenha a área real da ocorrência enviada pelo WAIP-Web (normalmente um polígono circular), não apenas um ponto marcador em seu centro - recorre ao ponto se nenhum polígono estiver disponível. A decodificação de palavras-chave do serviço de resgate agora é ativada por padrão para novas instalações (antes desativada), assim como a caixa de seleção de processamento do serviço de resgate. Uma frase de justificativa redundante foi removida das descrições de ambas as caixas de seleção. A área da ocorrência agora também permanece sempre totalmente visível - o adaptador reduz automaticamente o zoom além do nível configurado, se necessário, em vez de cortá-la na borda da imagem. A cor e a espessura do contorno agora também são configuráveis.",
80
- "ru": "Изображение карты вызова теперь отображает реальную зону вызова, отправленную WAIP-Web (обычно круговой полигон), а не просто точку-маркер в её центре - при отсутствии полигона используется точка. Декодирование ключевых слов скорой помощи теперь по умолчанию включено для новых установок (ранее было выключено), как и флажок обработки скорой помощи. Из описаний обоих флажков удалено избыточное поясняющее предложение. Зона вызова теперь также всегда остаётся полностью видимой - адаптер при необходимости автоматически уменьшает масштаб за пределы настроенного уровня, вместо того чтобы обрезать её по краю изображения. Цвет и толщина контура теперь также настраиваются.",
81
- "uk": "Зображення карти виклику тепер відображає реальну зону виклику, надіслану WAIP-Web (зазвичай круговий полігон), а не лише точку-маркер у її центрі - за відсутності полігона використовується точка. Декодування ключових слів швидкої допомоги тепер типово увімкнено для нових інсталяцій (раніше було вимкнено), як і прапорець обробки швидкої допомоги. З описів обох прапорців видалено зайве пояснювальне речення. Зона виклику тепер також завжди залишається повністю видимою - адаптер за потреби автоматично зменшує масштаб за межі налаштованого рівня, замість того щоб обрізати її по краю зображення. Колір і товщина контуру тепер також налаштовуються.",
82
- "zh-cn": "事件地图图像现在会绘制 WAIP-Web 发送的实际事件区域(通常是圆形多边形),而不仅仅是在其中心显示一个圆点标记——如果没有可用的多边形,则回退为圆点。急救服务关键字解码现在默认对新安装启用(之前默认关闭),与急救服务处理复选框保持一致。已从两个复选框的说明中删除了多余的说明句。 现在事件区域也始终保持完全可见——如有必要,适配器会自动缩小超出配置的缩放级别,而不是在图像边缘裁剪该区域。 轮廓的颜色和粗细现在也可配置。"
83
- },
84
- "0.7.28": {
85
- "en": "New: \"Process rescue-service incidents\" checkbox (on by default) on the renamed \"Rescue service\" tab - when unchecked, incidents identified as rescue-service calls via einsatzart are ignored completely (no states, no history, no TTS). New \"Incident map image\" tab: optionally generates an OpenStreetMap PNG marked with a dot, centered on each incident's coordinates, exposed via the new einsatz.kartenbildPfad state (configurable size/zoom, only the 10 most recent images kept).",
86
- "de": "Neu: Checkbox \"Rettungsdienst-Einsätze verarbeiten\" (standardmäßig an) auf dem umbenannten Tab \"Rettungsdienst\" - deaktiviert werden über einsatzart als Rettungsdienst erkannte Einsätze komplett ignoriert (keine States, keine History, kein TTS). Neuer Tab \"Einsatzkarte\": erzeugt optional ein mit einem Punkt markiertes OpenStreetMap-PNG, zentriert auf die Einsatz-Koordinaten, über den neuen State einsatz.kartenbildPfad bereitgestellt (Größe/Zoom konfigurierbar, nur die letzten 10 Bilder werden aufgehoben).",
87
- "ru": "Новое: флажок \"Обрабатывать вызовы скорой помощи\" (по умолчанию включён) на переименованной вкладке \"Скорая помощь\" - если снят, вызовы, определённые как вызовы скорой помощи через einsatzart, полностью игнорируются (без состояний, без истории, без TTS). Новая вкладка \"Изображение карты вызова\": по желанию создаёт отмеченное точкой PNG-изображение OpenStreetMap, центрированное на координатах каждого вызова, доступное через новое состояние einsatz.kartenbildPfad (настраиваемый размер/масштаб, хранятся только 10 последних изображений).",
88
- "pt": "Novidade: caixa de seleção \"Processar ocorrências do serviço de resgate\" (ativada por padrão) na aba renomeada \"Serviço de resgate\" - se desmarcada, as ocorrências identificadas como chamados do serviço de resgate via einsatzart são completamente ignoradas (sem estados, sem histórico, sem TTS). Nova aba \"Imagem de mapa da ocorrência\": gera opcionalmente um PNG do OpenStreetMap marcado com um ponto, centrado nas coordenadas de cada ocorrência, exposto através do novo estado einsatz.kartenbildPfad (tamanho/zoom configuráveis, apenas as 10 imagens mais recentes são mantidas).",
89
- "nl": "Nieuw: selectievakje \"Reddingsdienst-incidenten verwerken\" (standaard ingeschakeld) op het hernoemde tabblad \"Reddingsdienst\" - indien uitgeschakeld, worden via einsatzart als reddingsdienstmelding herkende incidenten volledig genegeerd (geen states, geen geschiedenis, geen TTS). Nieuw tabblad \"Incidentkaartafbeelding\": genereert optioneel een met een stip gemarkeerde OpenStreetMap-PNG, gecentreerd op de coördinaten van elk incident, beschikbaar via de nieuwe state einsatz.kartenbildPfad (grootte/zoom instelbaar, alleen de 10 meest recente afbeeldingen worden bewaard).",
90
- "fr": "Nouveau : case à cocher \"Traiter les incidents du service de secours\" (activée par défaut) sur l'onglet renommé \"Service de secours\" - si désactivée, les incidents identifiés comme des appels du service de secours via einsatzart sont complètement ignorés (aucun état, aucun historique, aucun TTS). Nouvel onglet \"Image de carte de l'incident\" : génère en option un PNG OpenStreetMap marqué d'un point, centré sur les coordonnées de chaque incident, exposé via le nouvel état einsatz.kartenbildPfad (taille/zoom configurables, seules les 10 images les plus récentes sont conservées).",
91
- "it": "Novità: casella \"Elaborare gli incidenti del servizio di soccorso\" (attiva per impostazione predefinita) nella scheda rinominata \"Servizio di soccorso\" - se disattivata, gli incidenti identificati come chiamate del servizio di soccorso tramite einsatzart vengono ignorati completamente (nessuno stato, nessuna cronologia, nessun TTS). Nuova scheda \"Immagine della mappa dell'incidente\": genera facoltativamente un PNG di OpenStreetMap contrassegnato con un punto, centrato sulle coordinate di ogni incidente, esposto tramite il nuovo stato einsatz.kartenbildPfad (dimensione/zoom configurabili, vengono conservate solo le 10 immagini più recenti).",
92
- "es": "Novedad: casilla \"Procesar incidentes del servicio de rescate\" (activada por defecto) en la pestaña renombrada \"Servicio de rescate\" - si se desactiva, los incidentes identificados como avisos del servicio de rescate mediante einsatzart se ignoran por completo (sin estados, sin historial, sin TTS). Nueva pestaña \"Imagen de mapa del incidente\": genera opcionalmente un PNG de OpenStreetMap marcado con un punto, centrado en las coordenadas de cada incidente, disponible mediante el nuevo estado einsatz.kartenbildPfad (tamaño/zoom configurables, solo se conservan las 10 imágenes más recientes).",
93
- "pl": "Nowość: pole wyboru \"Przetwarzaj zdarzenia ratownictwa medycznego\" (domyślnie włączone) na przemianowanej karcie \"Ratownictwo medyczne\" - po odznaczeniu zdarzenia rozpoznane jako wezwania ratownictwa medycznego poprzez einsatzart są całkowicie ignorowane (brak stanów, historii, TTS). Nowa karta \"Obraz mapy zdarzenia\": opcjonalnie generuje oznaczony kropką obraz PNG OpenStreetMap, wyśrodkowany na współrzędnych każdego zdarzenia, udostępniany przez nowy stan einsatz.kartenbildPfad (konfigurowalny rozmiar/zoom, przechowywanych jest tylko 10 najnowszych obrazów).",
94
- "uk": "Новинка: прапорець \"Обробляти виклики швидкої допомоги\" (типово увімкнено) на перейменованій вкладці \"Швидка допомога\" - якщо знято, виклики, визначені як виклики швидкої допомоги через einsatzart, повністю ігноруються (без станів, без історії, без TTS). Нова вкладка \"Зображення карти виклику\": за бажанням створює позначене крапкою PNG-зображення OpenStreetMap, центроване на координатах кожного виклику, доступне через новий стан einsatz.kartenbildPfad (настроюваний розмір/масштаб, зберігаються лише 10 останніх зображень).",
95
- "zh-cn": "新增:在重命名后的\"急救服务\"标签页中新增\"处理急救服务事件\"复选框(默认启用)——取消勾选后,通过 einsatzart 识别为急救服务呼叫的事件将被完全忽略(无状态更新、无历史记录、无语音播报)。新增\"事件地图图像\"标签页:可选地生成以圆点标记、以每个事件坐标为中心的 OpenStreetMap PNG 图像,通过新状态 einsatz.kartenbildPfad 提供(尺寸/缩放可配置,仅保留最近 10 张图像)。"
96
96
  }
97
97
  },
98
98
  "titleLang": {
package/main.js CHANGED
@@ -19,7 +19,7 @@
19
19
  * flache Arrays in einsatz.json.routen/.rueckmeldungen/.emAlarmiert/
20
20
  * .emWeitere - nur für den jeweils aktuellen Einsatz, nicht historisiert.
21
21
  * Ergänzt um schnell bindbare Zähler (einsatz.routenGesamt,
22
- * einsatz.rueckmeldungGesamt, einsatz.rueckmeldungAnzahl.*). Der frühere
22
+ * einsatz.rueckmeldungenGesamt, einsatz.rueckmeldungen.*). Der frühere
23
23
  * vis.*-Kanal entfällt komplett.
24
24
  *
25
25
  * EN: ioBroker.WAIP-Web
@@ -39,8 +39,8 @@
39
39
  * resources live as their own, likewise flat arrays in
40
40
  * einsatz.json.routen/.rueckmeldungen/.emAlarmiert/.emWeitere - only for
41
41
  * the currently running incident, not historized. Complemented by
42
- * quick-to-bind counters (einsatz.routenGesamt, einsatz.rueckmeldungGesamt,
43
- * einsatz.rueckmeldungAnzahl.*). The former vis.* channel is gone entirely.
42
+ * quick-to-bind counters (einsatz.routenGesamt, einsatz.rueckmeldungenGesamt,
43
+ * einsatz.rueckmeldungen.*). The former vis.* channel is gone entirely.
44
44
  */
45
45
 
46
46
  const https = require('node:https');
@@ -99,11 +99,27 @@ const ALLOWED_EINSATZ_FIELDS = [
99
99
  'ortsteil',
100
100
  'ablaufzeit',
101
101
  'sondersignal',
102
- // DE: laut client_waip.js (offizielles Frontend) zusätzlich vorhandenes Feld:
103
- // EN: additional field per client_waip.js (the official frontend):
104
- 'zeitstempel',
102
+ // DE: Das vom Server als "zeitstempel" gesendete Feld (laut client_waip.js, dem
103
+ // offiziellen Frontend, zusätzlich vorhanden) landet als einsatz.alarmierungszeit -
104
+ // bewusst NICHT hier, sondern wie beschreibung als Sonderfall in handleAlarm()
105
+ // behandelt, da der State-Name vom Server-Feldnamen abweicht.
106
+ // EN: The field the server sends as "zeitstempel" (per client_waip.js, the official
107
+ // frontend, an additional field) ends up as einsatz.alarmierungszeit - deliberately
108
+ // NOT listed here, but handled as a special case in handleAlarm() like beschreibung,
109
+ // since the state name differs from the server's field name.
105
110
  ];
106
- const RUECKMELDUNG_ANZAHL_KEYS = ['ek', 'gf', 'zf', 'vf', 'agt', 'fzf', 'ma', 'med'];
111
+ // DE: Rückmeldungs-Zähler sind seit 0.7.35 in zwei Unter-Kanäle unter einsatz.rueckmeldungen
112
+ // gruppiert - "rollen" (aus rmld_role abgeleitet) und "funktionen" (aus den
113
+ // rmld_capability_*-Flags abgeleitet), siehe updateRueckmeldungCounts(). Vorher lagen alle
114
+ // acht Zähler flach direkt unter einsatz.rueckmeldungAnzahl (0.7.35: einsatz.rueckmeldungAnzahl.
115
+ // rollen/.funktionen; der Kanal selbst hieß erst ab 0.7.36 einsatz.rueckmeldungen).
116
+ // EN: Feedback counters have been grouped into two sub-channels under einsatz.rueckmeldungen
117
+ // since 0.7.35 - "rollen" (derived from rmld_role) and "funktionen" (derived from the
118
+ // rmld_capability_* flags), see updateRueckmeldungCounts(). Previously all eight counters
119
+ // lived flat directly under einsatz.rueckmeldungAnzahl (0.7.35: einsatz.rueckmeldungAnzahl.
120
+ // rollen/.funktionen; the channel itself was only renamed to einsatz.rueckmeldungen in 0.7.36).
121
+ const RUECKMELDUNG_ROLLEN_KEYS = ['ek', 'gf', 'zf', 'vf'];
122
+ const RUECKMELDUNG_FUNKTIONEN_KEYS = ['agt', 'fzf', 'ma', 'med'];
107
123
  // DE: identische Disconnect-Logs 60s lang unterdrücken
108
124
  // EN: suppress identical disconnect logs for 60s
109
125
  const DISCONNECT_DEDUPE_MS = 60000;
@@ -259,6 +275,70 @@ const OBSOLETE_OBJECT_IDS = [
259
275
  'einsatz.hausnummer',
260
276
  'einsatz.einsatzdetails',
261
277
  'einsatz.permissions',
278
+ // DE: Umstrukturierung in 0.7.35: die acht Rückmeldungs-Zähler ziehen von direkt unter
279
+ // einsatz.rueckmeldungAnzahl in die neuen Unter-Kanäle .rollen/.funktionen um (siehe
280
+ // CHANNEL_DEFS/STATE_DEFS) - die alten flachen State-Blätter müssen daher vor
281
+ // initObjects() entfernt werden, sonst blieben sie als verwaiste States neben den neuen
282
+ // verschachtelten Pfaden bestehen.
283
+ // EN: Restructuring in 0.7.35: the eight feedback counters move from directly under
284
+ // einsatz.rueckmeldungAnzahl into the new .rollen/.funktionen sub-channels (see
285
+ // CHANNEL_DEFS/STATE_DEFS) - the old flat state leaves must therefore be removed before
286
+ // initObjects() runs, otherwise they'd linger as orphaned states alongside the new
287
+ // nested paths.
288
+ 'einsatz.rueckmeldungAnzahl.ek',
289
+ 'einsatz.rueckmeldungAnzahl.gf',
290
+ 'einsatz.rueckmeldungAnzahl.zf',
291
+ 'einsatz.rueckmeldungAnzahl.vf',
292
+ 'einsatz.rueckmeldungAnzahl.agt',
293
+ 'einsatz.rueckmeldungAnzahl.fzf',
294
+ 'einsatz.rueckmeldungAnzahl.ma',
295
+ 'einsatz.rueckmeldungAnzahl.med',
296
+ // DE: Umstrukturierung in 0.7.36: der Kanal einsatz.rueckmeldungAnzahl (inkl. seiner in
297
+ // 0.7.35 eingeführten Unter-Kanäle .rollen/.funktionen) heißt jetzt einsatz.rueckmeldungen,
298
+ // einsatz.rueckmeldungGesamt heißt jetzt einsatz.rueckmeldungenGesamt und einsatz.zeitstempel
299
+ // heißt jetzt einsatz.alarmierungszeit. Die acht State-Blätter aus 0.7.35
300
+ // (einsatz.rueckmeldungAnzahl.rollen.*/.funktionen.*) sind hier gelistet, damit sie beim
301
+ // Update von 0.7.35 entfernt werden; die dann leeren alten Ordner selbst werden von
302
+ // OBSOLETE_FOLDER_IDS unten erfasst (cleanupObsoleteObjects() löscht hier oben bewusst nur
303
+ // States, nie Channel/Folder, siehe dort).
304
+ // EN: Restructuring in 0.7.36: the einsatz.rueckmeldungAnzahl channel (including its
305
+ // .rollen/.funktionen sub-channels introduced in 0.7.35) is now einsatz.rueckmeldungen,
306
+ // einsatz.rueckmeldungGesamt is now einsatz.rueckmeldungenGesamt, and einsatz.zeitstempel is
307
+ // now einsatz.alarmierungszeit. The eight 0.7.35 state leaves
308
+ // (einsatz.rueckmeldungAnzahl.rollen.*/.funktionen.*) are listed here so they get removed
309
+ // when upgrading from 0.7.35; the then-empty old folders themselves are covered by
310
+ // OBSOLETE_FOLDER_IDS below (cleanupObsoleteObjects() deliberately only ever deletes states
311
+ // here, never channels/folders, see there).
312
+ 'einsatz.rueckmeldungAnzahl.rollen.ek',
313
+ 'einsatz.rueckmeldungAnzahl.rollen.gf',
314
+ 'einsatz.rueckmeldungAnzahl.rollen.zf',
315
+ 'einsatz.rueckmeldungAnzahl.rollen.vf',
316
+ 'einsatz.rueckmeldungAnzahl.funktionen.agt',
317
+ 'einsatz.rueckmeldungAnzahl.funktionen.fzf',
318
+ 'einsatz.rueckmeldungAnzahl.funktionen.ma',
319
+ 'einsatz.rueckmeldungAnzahl.funktionen.med',
320
+ 'einsatz.rueckmeldungGesamt',
321
+ 'einsatz.zeitstempel',
322
+ ];
323
+
324
+ // DE: Wie OBSOLETE_OBJECT_IDS, aber für Channel-/Folder-Objekte, die bei einer Umbenennung
325
+ // übrig bleiben würden: cleanupObsoleteObjects() löscht dort bewusst nur obj.type === 'state',
326
+ // nie Channel/Folder, um ein absichtlich zum Channel gewordenes State-Blatt nicht versehentlich
327
+ // zu löschen (siehe einsatz.json in 0.7.15). Diese Sorge gilt für die hier gelisteten IDs nicht,
328
+ // da der jeweilige Pfad komplett aufgegeben wurde - STATE_DEFS/CHANNEL_DEFS definieren dort
329
+ // nichts mehr, es kann also nie wieder legitim ein Objekt an dieser ID entstehen. Werden daher
330
+ // unabhängig vom aktuellen obj.type gelöscht. Reihenfolge: Kind-Ordner vor Eltern-Ordner.
331
+ // EN: Like OBSOLETE_OBJECT_IDS, but for channel/folder objects that would otherwise linger
332
+ // after a rename: cleanupObsoleteObjects() deliberately only ever deletes obj.type === 'state'
333
+ // there, never channels/folders, to avoid accidentally deleting a leaf that deliberately became
334
+ // a channel (see einsatz.json in 0.7.15). That concern doesn't apply to the IDs listed here,
335
+ // since the path itself has been abandoned entirely - STATE_DEFS/CHANNEL_DEFS no longer define
336
+ // anything there, so a legitimate object can never reappear at this ID again. Deleted regardless
337
+ // of their current obj.type. Order: child folders before the parent folder.
338
+ const OBSOLETE_FOLDER_IDS = [
339
+ 'einsatz.rueckmeldungAnzahl.rollen',
340
+ 'einsatz.rueckmeldungAnzahl.funktionen',
341
+ 'einsatz.rueckmeldungAnzahl',
262
342
  ];
263
343
 
264
344
  // DE: Übergeordnete Channel/Folder-Objekte, die für jeden State-Zweig existieren müssen.
@@ -270,7 +350,9 @@ const OBSOLETE_OBJECT_IDS = [
270
350
  const CHANNEL_DEFS = [
271
351
  { id: 'status', type: 'channel', name: 'Verbindungs- und Registrierungsstatus' },
272
352
  { id: 'einsatz', type: 'channel', name: 'Aktueller Einsatz' },
273
- { id: 'einsatz.rueckmeldungAnzahl', type: 'folder', name: 'Rückmeldungen nach Funktion' },
353
+ { id: 'einsatz.rueckmeldungen', type: 'folder', name: 'Rückmeldungen nach Rolle/Funktion' },
354
+ { id: 'einsatz.rueckmeldungen.rollen', type: 'folder', name: 'Rückmeldungen nach Rolle' },
355
+ { id: 'einsatz.rueckmeldungen.funktionen', type: 'folder', name: 'Rückmeldungen nach Funktion' },
274
356
  { id: 'einsatz.json', type: 'folder', name: 'Einsatzdaten als flache JSON-Objekte/Arrays für Tabellen-Widgets' },
275
357
  { id: 'einsatz.tts', type: 'folder', name: 'TTS-Ansage des aktuellen Einsatzes' },
276
358
  { id: 'debug', type: 'channel', name: 'Diagnose- und Debug-Informationen' },
@@ -349,7 +431,7 @@ const STATE_DEFS = [
349
431
  },
350
432
  { id: 'einsatz.ort', type: 'string', role: 'text', name: 'Ort' },
351
433
  { id: 'einsatz.ortsteil', type: 'string', role: 'text', name: 'Ortsteil' },
352
- { id: 'einsatz.zeitstempel', type: 'string', role: 'date', name: 'Alarmzeitstempel' },
434
+ { id: 'einsatz.alarmierungszeit', type: 'string', role: 'date', name: 'Alarmierungszeit' },
353
435
  { id: 'einsatz.ablaufzeit', type: 'string', role: 'date', name: 'Ablaufzeit' },
354
436
  { id: 'einsatz.sondersignal', type: 'number', role: 'value', name: 'Sondersignal', def: 0 },
355
437
  { id: 'einsatz.latitude', type: 'number', role: 'value.gps.latitude', name: 'Breitengrad' },
@@ -408,51 +490,63 @@ const STATE_DEFS = [
408
490
  // EN: derived counters
409
491
  { id: 'einsatz.routenGesamt', type: 'number', role: 'value', name: 'Anzahl Routen im aktuellen Einsatz', def: 0 },
410
492
  {
411
- id: 'einsatz.rueckmeldungGesamt',
493
+ id: 'einsatz.rueckmeldungenGesamt',
412
494
  type: 'number',
413
495
  role: 'value',
414
496
  name: 'Rückmeldungen gesamt im aktuellen Einsatz',
415
497
  def: 0,
416
498
  },
417
499
  {
418
- id: 'einsatz.rueckmeldungAnzahl.ek',
500
+ id: 'einsatz.rueckmeldungen.rollen.ek',
419
501
  type: 'number',
420
502
  role: 'value',
421
503
  name: 'Rückmeldungen: Einsatzkräfte',
422
504
  def: 0,
423
505
  },
424
506
  {
425
- id: 'einsatz.rueckmeldungAnzahl.gf',
507
+ id: 'einsatz.rueckmeldungen.rollen.gf',
426
508
  type: 'number',
427
509
  role: 'value',
428
510
  name: 'Rückmeldungen: Gruppenführer',
429
511
  def: 0,
430
512
  },
431
- { id: 'einsatz.rueckmeldungAnzahl.zf', type: 'number', role: 'value', name: 'Rückmeldungen: Zugführer', def: 0 },
432
513
  {
433
- id: 'einsatz.rueckmeldungAnzahl.vf',
514
+ id: 'einsatz.rueckmeldungen.rollen.zf',
515
+ type: 'number',
516
+ role: 'value',
517
+ name: 'Rückmeldungen: Zugführer',
518
+ def: 0,
519
+ },
520
+ {
521
+ id: 'einsatz.rueckmeldungen.rollen.vf',
434
522
  type: 'number',
435
523
  role: 'value',
436
524
  name: 'Rückmeldungen: Verbandsführer',
437
525
  def: 0,
438
526
  },
439
527
  {
440
- id: 'einsatz.rueckmeldungAnzahl.agt',
528
+ id: 'einsatz.rueckmeldungen.funktionen.agt',
441
529
  type: 'number',
442
530
  role: 'value',
443
531
  name: 'Rückmeldungen: Atemschutzgeräteträger',
444
532
  def: 0,
445
533
  },
446
534
  {
447
- id: 'einsatz.rueckmeldungAnzahl.fzf',
535
+ id: 'einsatz.rueckmeldungen.funktionen.fzf',
448
536
  type: 'number',
449
537
  role: 'value',
450
538
  name: 'Rückmeldungen: Fahrzeugführer',
451
539
  def: 0,
452
540
  },
453
- { id: 'einsatz.rueckmeldungAnzahl.ma', type: 'number', role: 'value', name: 'Rückmeldungen: Maschinisten', def: 0 },
454
541
  {
455
- id: 'einsatz.rueckmeldungAnzahl.med',
542
+ id: 'einsatz.rueckmeldungen.funktionen.ma',
543
+ type: 'number',
544
+ role: 'value',
545
+ name: 'Rückmeldungen: Maschinisten',
546
+ def: 0,
547
+ },
548
+ {
549
+ id: 'einsatz.rueckmeldungen.funktionen.med',
456
550
  type: 'number',
457
551
  role: 'value',
458
552
  name: 'Rückmeldungen: Medizinisch/Sanitäter',
@@ -1265,7 +1359,9 @@ class WaipWeb extends utils.Adapter {
1265
1359
  value type) explicitly checks that this is really still the old state leaf - relevant
1266
1360
  for IDs like einsatz.json, which changed from state to channel in the 0.7.15
1267
1361
  restructuring but kept the same ID: without this check, the by-now correctly created
1268
- channel would otherwise get deleted and recreated by initObjects() on every restart. */
1362
+ channel would otherwise get deleted and recreated by initObjects() on every restart.
1363
+ Also removes OBSOLETE_FOLDER_IDS - channel/folder objects at paths abandoned entirely
1364
+ by a rename, where that same type-check doesn't apply (see its own comment). */
1269
1365
  async cleanupObsoleteObjects() {
1270
1366
  for (const id of OBSOLETE_OBJECT_IDS) {
1271
1367
  try {
@@ -1278,6 +1374,17 @@ class WaipWeb extends utils.Adapter {
1278
1374
  /* DE: ignorieren - Objekt existierte vermutlich nicht / EN: ignore - object probably didn't exist */
1279
1375
  }
1280
1376
  }
1377
+ for (const id of OBSOLETE_FOLDER_IDS) {
1378
+ try {
1379
+ const obj = await this.getObjectAsync(id);
1380
+ if (obj) {
1381
+ await this.delObjectAsync(id);
1382
+ this.log.info(`Removed obsolete folder object from a previous version: ${id}`);
1383
+ }
1384
+ } catch {
1385
+ /* DE: ignorieren - Objekt existierte vermutlich nicht / EN: ignore - object probably didn't exist */
1386
+ }
1387
+ }
1281
1388
  }
1282
1389
 
1283
1390
  /* DE: Löscht bestehende State-Objekte, deren common.type oder common.role nicht mehr zur
@@ -2405,6 +2512,16 @@ class WaipWeb extends utils.Adapter {
2405
2512
  // but is determined locally by handleAlarm() and carried along in the snapshot (see
2406
2513
  // lookupStichwortBeschreibung()).
2407
2514
  flat.beschreibung = Object.prototype.hasOwnProperty.call(src, 'beschreibung') ? src.beschreibung : null;
2515
+ // DE: alarmierungszeit kommt vom Server als "zeitstempel" und wird ebenfalls als
2516
+ // Sonderfall im Snapshot mitgeführt (siehe handleAlarm()), da der State-Name vom
2517
+ // Server-Feldnamen abweicht - daher nicht in ALLOWED_EINSATZ_FIELDS.
2518
+ // EN: alarmierungszeit comes from the server as "zeitstempel" and is likewise
2519
+ // carried along in the snapshot as a special case (see handleAlarm()), since the
2520
+ // state name differs from the server's field name - hence not in
2521
+ // ALLOWED_EINSATZ_FIELDS.
2522
+ flat.alarmierungszeit = Object.prototype.hasOwnProperty.call(src, 'alarmierungszeit')
2523
+ ? src.alarmierungszeit
2524
+ : null;
2408
2525
  flat.registeredMonitor = this.currentMonitor || null;
2409
2526
  flat.registeredMonitorName = this.monitorName || null;
2410
2527
  return flat;
@@ -2624,10 +2741,14 @@ class WaipWeb extends utils.Adapter {
2624
2741
 
2625
2742
  /* DE: Berechnet aus den im Snapshot gesammelten Rückmeldungen die Zähler pro Rolle/Fähigkeit
2626
2743
  (analog zu den Badges EK/GF/ZF/VF/AGT/FZF/MA/MED/Gesamt der Weboberfläche) und
2627
- aktualisiert einsatz.rueckmeldungAnzahl.* sowie einsatz.rueckmeldungGesamt.
2744
+ aktualisiert einsatz.rueckmeldungen.rollen.<k> und .funktionen.<k> sowie
2745
+ einsatz.rueckmeldungenGesamt. EK/GF/ZF/VF (aus rmld_role) liegen unter .rollen, AGT/FZF/MA/
2746
+ MED (aus den rmld_capability_*-Flags) unter .funktionen.
2628
2747
  EN: Computes the per-role/skill counters from the feedback entries collected in the
2629
2748
  snapshot (mirroring the EK/GF/ZF/VF/AGT/FZF/MA/MED/total badges of the web UI) and
2630
- updates einsatz.rueckmeldungAnzahl.* as well as einsatz.rueckmeldungGesamt. */
2749
+ updates einsatz.rueckmeldungen.rollen.<k> and .funktionen.<k> as well as
2750
+ einsatz.rueckmeldungenGesamt. EK/GF/ZF/VF (from rmld_role) live under .rollen, AGT/FZF/MA/
2751
+ MED (from the rmld_capability_* flags) under .funktionen. */
2631
2752
  async updateRueckmeldungCounts() {
2632
2753
  const list = (this.currentEinsatzSnapshot && this.currentEinsatzSnapshot.rueckmeldungen) || [];
2633
2754
  const counts = { ek: 0, gf: 0, zf: 0, vf: 0, agt: 0, fzf: 0, ma: 0, med: 0 };
@@ -2654,10 +2775,15 @@ class WaipWeb extends utils.Adapter {
2654
2775
  counts.med++;
2655
2776
  }
2656
2777
  }
2657
- const tasks = RUECKMELDUNG_ANZAHL_KEYS.map(k =>
2658
- this.setStateAsync(`einsatz.rueckmeldungAnzahl.${k}`, counts[k], true),
2659
- );
2660
- tasks.push(this.setStateAsync('einsatz.rueckmeldungGesamt', list.length, true));
2778
+ const tasks = [
2779
+ ...RUECKMELDUNG_ROLLEN_KEYS.map(k =>
2780
+ this.setStateAsync(`einsatz.rueckmeldungen.rollen.${k}`, counts[k], true),
2781
+ ),
2782
+ ...RUECKMELDUNG_FUNKTIONEN_KEYS.map(k =>
2783
+ this.setStateAsync(`einsatz.rueckmeldungen.funktionen.${k}`, counts[k], true),
2784
+ ),
2785
+ ];
2786
+ tasks.push(this.setStateAsync('einsatz.rueckmeldungenGesamt', list.length, true));
2661
2787
  const results = await Promise.allSettled(tasks);
2662
2788
  for (const r of results) {
2663
2789
  if (r.status === 'rejected') {
@@ -2843,6 +2969,17 @@ class WaipWeb extends utils.Adapter {
2843
2969
  this.currentEinsatzSnapshot.emWeitere = data.em_weitere;
2844
2970
  }
2845
2971
 
2972
+ // DE: Server-Feld "zeitstempel" -> State/Snapshot-Feld einsatz.alarmierungszeit -
2973
+ // bewusst als Sonderfall behandelt (nicht in ALLOWED_EINSATZ_FIELDS), da der
2974
+ // State-Name vom Server-Feldnamen abweicht.
2975
+ // EN: Server field "zeitstempel" -> einsatz.alarmierungszeit state/snapshot field -
2976
+ // deliberately handled as a special case (not in ALLOWED_EINSATZ_FIELDS), since
2977
+ // the state name differs from the server's field name.
2978
+ if (Object.prototype.hasOwnProperty.call(data, 'zeitstempel')) {
2979
+ this.currentEinsatzSnapshot.alarmierungszeit = data.zeitstempel;
2980
+ tasks.push(this.setField('einsatz.alarmierungszeit', data.zeitstempel));
2981
+ }
2982
+
2846
2983
  // DE: Beschreibung zum Stichwort lokal ermitteln (kommt nicht vom Server) und wie die
2847
2984
  // übrigen flachen Felder setzen/im Snapshot mitführen.
2848
2985
  // EN: Determine the keyword's description locally (doesn't come from the server)
@@ -2969,6 +3106,13 @@ class WaipWeb extends utils.Adapter {
2969
3106
  async clearCurrentEinsatzStates() {
2970
3107
  const tasks = this.ALLOWED_EINSATZ_FIELDS.map(k => this.setStateAsync(`einsatz.${k}`, null, true));
2971
3108
  tasks.push(this.setStateAsync('einsatz.beschreibung', null, true));
3109
+ // DE: alarmierungszeit ist wie beschreibung ein Sonderfall (nicht in
3110
+ // ALLOWED_EINSATZ_FIELDS, siehe handleAlarm()) und muss daher hier separat geleert
3111
+ // werden.
3112
+ // EN: alarmierungszeit is a special case like beschreibung (not in
3113
+ // ALLOWED_EINSATZ_FIELDS, see handleAlarm()), so it needs to be cleared separately
3114
+ // here.
3115
+ tasks.push(this.setStateAsync('einsatz.alarmierungszeit', null, true));
2972
3116
  tasks.push(this.setStateAsync('einsatz.latitude', null, true));
2973
3117
  tasks.push(this.setStateAsync('einsatz.longitude', null, true));
2974
3118
  // DE: Anders als einsatz.tts.last (dessen Vorbild ursprünglich für kartenbildPfad
@@ -2994,9 +3138,9 @@ class WaipWeb extends utils.Adapter {
2994
3138
 
2995
3139
  this.currentEinsatzUuid = null;
2996
3140
  this.currentEinsatzSnapshot = null;
2997
- // DE: rueckmeldungGesamt/rueckmeldungAnzahl.* liest aus this.currentEinsatzSnapshot,
3141
+ // DE: rueckmeldungenGesamt/rueckmeldungen.* liest aus this.currentEinsatzSnapshot,
2998
3142
  // ist jetzt also null -> alle Zähler werden konsistent auf 0 zurückgesetzt.
2999
- // EN: rueckmeldungGesamt/rueckmeldungAnzahl.* reads from this.currentEinsatzSnapshot,
3143
+ // EN: rueckmeldungenGesamt/rueckmeldungen.* reads from this.currentEinsatzSnapshot,
3000
3144
  // which is now null -> all counters get consistently reset to 0.
3001
3145
  await this.updateRueckmeldungCounts();
3002
3146
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.waip-web",
3
- "version": "0.7.34",
3
+ "version": "0.7.36",
4
4
  "description": "Wachalarm IP-Web (WAIP) Adapter für ioBroker – bindet Alarmierungen, Rückmeldungen, Routen und TTS-Ansagen per Socket.IO an ioBroker an.",
5
5
  "author": {
6
6
  "name": "rnc11",