WAIP-Web

Подключается к монитору диспетчеризации WAIP (Wachalarm-IP) через Socket.IO и отображает тревоги, обратную связь, маршруты и голосовые объявления TTS в виде состояний ioBroker.

Текущий релиз
1.0.0
Разработчик
rnc11
Лицензия
MIT

🇩🇪 README для немецкой версии

Адаптер ioBroker для WACHALARM IP-Web (WAIP-Web)

Подключается через Socket.IO к монитору диспетчеризации WAIP-Web и отображает инциденты («Einsatz»), отзывы операторов («Rückmeldung»), маршруты и объявления TTS в состояниях ioBroker - без необходимости держать открытой вкладку браузера.

Оглавление

einsatzAktuell.json · einsatzAktuell.tts · [dashboard-states · [debug]](#debug)

Об этом адаптере

Этот адаптер является независимым проектом, созданным сообществом и не имеет никакого отношения к проекту WAIP-Web, к Robert-112 или к оператору какого-либо конкретного экземпляра (например, Интегрированного регионального диспетчерского центра Лаузиц / Integrierte Regionalleitstelle Lausitz). Он был создан на основе анализа поведения интерфейса (client_waip.js), который экземпляр WAIP-Web публично предоставляет любому браузеру, чтобы воспроизвести те же события и поля данных Socket.IO, которые получает обычный браузерный клиент.

Адаптер подключается без авторизации и, следовательно, получает только общедоступные данные уровня доступа WAIP-Web (ключевое слово, местоположение, приблизительное местоположение, оповещаемые ресурсы, обратная связь) - те же данные, которые увидит любой анонимный посетитель браузера без авторизации. Никакие ограничения доступа не обходятся.

Примечание: Постоянно работающий автоматизированный клиент, подобный этому адаптеру, отличается от периодически открываемой вкладки браузера. Прежде чем запускать его в рабочей среде, кратко уточните у оператора/вашего диспетчерского центра, приветствуется ли постоянное автоматизированное подключение.

О WAIP-Web

Wachalarm IP-Web - это веб-приложение с открытым исходным кодом от Robert-112, которое отображает информацию о вызовах/оповещениях для пожарных служб и служб скорой медицинской помощи независимо от устройства в браузере (Windows, Linux, Mac, смартфон - установка не требуется). Среди прочего оно предлагает:

  • Монитор сигналов тревоги - тип инцидента, ключевое слово, специальный сигнал, местоположение,

карта, оповещенные ресурсы, обратная связь от служб реагирования через приложение, включая голосовые объявления.

  • Панель мониторинга - обзор всех текущих инцидентов.
  • Функция обратной связи - обратная связь от пользователей через приложение, сгруппированная по ролям.

(EK/GF/ZF/VF) и дополнительная квалификация (AGT/FZF/MA/MED)

  • Администрирование - управление пользователями, данные станций, обзор мониторов.

Сам WAIP-Web распространяется под лицензией Лицензия Creative Commons BY-SA 4.0. Этот адаптер не содержит кода из проекта WAIP-Web; он реализует независимый клиент для своего интерфейса Socket.IO.

Практические примеры использования

В этом разделе рассказывается о том, что вы можете реально создать с помощью состояний, предоставляемых этим адаптером - типичное использование в пожарной части/службе скорой помощи:

  • Настенный дисплей сигнализации. Привяжите einsatzAktuell.json.current к VIS

На настенном планшете или телевизоре в комнате отдыха/автомобильном холле автоматически отображаются табличный виджет: тип инцидента, ключевое слово, адрес и оповещенные ресурсы, без необходимости держать открытой вкладку браузера на этом экране (в этом и заключается основная причина существования этого адаптера).

  • Ключевые слова, написанные простым языком, на экранах и в уведомлениях.

einsatzAktuell.beschreibung преобразует загадочный код отправки (B:Wald groß/WSP, R1N0) в читаемое описание ("Wald-/Getreidefeldbrand (groß)", "Rettungswagen: 1, Notfalleinsatzfahrzeug: 0") - прикрепите его рядом с einsatzAktuell.stichwort на настенном дисплее или включите в push-уведомление/сообщение TTS, чтобы участникам не приходилось запоминать каждое ключевое слово.

  • Запускайте автоматические сценарии мгновенно по сигналу тревоги. Смотрите

einsatzAktuell.alarmAktiv (или info.connection вместе с ним) в правиле script/blockly для включения света в зале для транспортных средств, открытия ворот/двери, отправки push-уведомления (например, через адаптер Telegram/Pushover) с einsatzAktuell.stichwort/einsatzAktuell.beschreibung + einsatzAktuell.ort или мигания сценария умного освещения - все это через несколько секунд после фактического оповещения пейджера, без необходимости опроса, поскольку изменения состояния ioBroker срабатывают мгновенно.

  • Произнесите сигнал тревоги вслух. einsatzAktuell.tts.last - это

Готовый к воспроизведению абсолютный URL-адрес mp3; укажите на него автоматизацию в стиле sonos/snapcast/text2speech (или просто воспроизведите URL напрямую), чтобы о происшествии объявили через громкоговорители здания в момент срабатывания io.playtts - это полезно, когда не все члены группы смотрят на экран.

  • Живая численность персонала/доска отзывов. einsatzAktuell.rueckmeldungen.*

Счетчики (rollen.ek/.gf/.zf/.vf для каждой роли, funktionen.agt/.fzf/ .ma/.med для каждой квалификации) обновляются в режиме реального времени по мере подтверждения участниками через приложение - привяжите их к виджетам с индикаторами или цифрами для быстрого обзора «кто прибудет» во время реагирования.

  • Анализ инцидента / статистика. einsatzAktuell.json.history хранит

Последние N завершенных инцидентов (настраиваемое значение, по умолчанию 10) в виде плоской таблицы - привяжите ее ко второму представлению VIS или экспортируйте периодически (например, с помощью скрипта, считывающего состояние в io.standby), чтобы вести более длительный журнал или передавать количество инцидентов в адаптер панели мониторинга/статистики.

  • Обзор маршрута/транспортного средства на карте. einsatzAktuell.json.routen содержит

lat/lon и color для каждой станции реагирования - привяжите их к виджету карты VIS для быстрого визуального отображения того, кто находится в пути, независимо от самой карты WAIP-Web.

  • Взаимодействие с другими системами автоматизации ioBroker. Потому что каждое поле - это

Используя обычное состояние ioBroker, он взаимодействует со всем остальным, что уже запущено в экземпляре - пересылает einsatzAktuell.* в механизм сценариев умного дома, историю Grafana/InfluxDB для анализа времени отклика или поток в стиле Node-RED через адаптер ioBroker MQTT, не записывая ни одной строки в WAIP-Web API.

Функции

  • Подключается к пространству имен /waip через socket.io-client, регистрируется через

emit('WAIP', monitorId) один раз (использует REGISTRATION_TIMEOUT_MS в качестве резервного варианта, а не повторные отправки, поскольку избыточная отправка лишь заставляет сервер отвечать снова, не повышая надежность доставки)

  • Ручная обработка переподключения (автоматическое переподключение, встроенное в библиотеку, выполняется автоматически).

отключено) с настраиваемой задержкой

  • Истекло время ожидания регистрации с записью в журнал аудита (debug.monitorAudit)
  • Нормализация геоданных (поля wgs84, position или GeoJSON geometry)

→ центроид)

  • История последних N завершенных инцидентов (настраиваемое значение, по умолчанию 10);

einsatzAktuell.json.history)

  • Отдельные обработчики для сигнала тревоги (io.new_waip) и обратной связи (io.new_rmld),

маршруты (io.routes), TTS (io.playtts) и резервный режим (io.standby)

  • Автоматическое управление сессионными cookie-файлами (см. ниже), что обеспечивает доставку оповещений.

продолжает работать бесконечно без открытой сессии браузера.

  • Обнаружение перезапуска сервера с помощью io.version, с автоматической настройкой сессии.

обновить + переподключиться

  • Данные об инцидентах, обратной связи, маршрутах и оповещенных ресурсах доступны в следующем виде:

Отдельные плоские JSON-массивы в разделе einsatzAktuell.json.* - без вложенности, поэтому виджеты таблиц VIS могут напрямую к ним привязываться.

  • Сводные счетчики обратной связи по каждой роли/возможности, отражающие текущую ситуацию.

значки в веб-интерфейсе

  • Сброс состояния при каждом перезапуске: все состояния активно сбрасываются до исходных значений.

Пустое значение (false/0/null/[]) при запуске адаптера, за исключением einsatzAktuell.json.history и debug.monitorAudit (оба сохраняются после перезапуска). Обратите внимание, что если адаптер перезапускается во время активного инцидента, его активные поля (einsatzAktuell.*) также очищаются и заполняются заново только после того, как сервер отправит следующее событие для этого инцидента.

  • Защита от устаревших данных: когда новый инцидент возникает до предыдущего.

Поступили события маршрутизации/обратной связи для нового инцидента, einsatzAktuell.json.routen/.rueckmeldungen, и счетчики обратной связи обнуляются немедленно, а не в ожидании этих событий. И если io.standby когда-либо пропускается для инцидента (например, из-за разрыва соединения в неподходящий момент), сторожевой таймер автоматически завершает инцидент, как только ablaufzeit истекает с задержкой более чем в 60 секунд, вместо того, чтобы оставлять устаревшие «активные» данные на неопределенный срок.

  • Отображается только один последний активный инцидент; несколько инцидентов

В настоящее время одновременно активные инциденты можно просмотреть только на панели управления самого экземпляра WAIP-Web.

  • Необязательное описание на простом языке для einsatzAktuell.stichwort

(einsatzAktuell.beschreibung), определяется локально из поддерживаемой пользователем таблицы ключевых слов плюс необязательный декодер для схемы ключевых слов службы спасения R<RTW>N<NEF>, используемой несколькими диспетчерскими центрами - см. Спасательная служба

  • Происшествия, связанные со спасательными службами, можно полностью игнорировать (ни штатов, ни...).

история, без TTS) - полезно в тех случаях, когда WAIP изначально подает им ненадежные сигналы, см. Спасательная служба

  • Дополнительное изображение карты происшествия: PNG-файл, центрированный на месте происшествия.

Координаты, составленные локально из тайлов OpenStreetMap, с областью инцидента, отправляемой WAIP-Web, отображаемой в виде контура с настраиваемым цветом/толщиной (можно заменить на обычную точку-маркер), автоматически уменьшаются по мере необходимости, чтобы вся область оставалась видимой, путь к файлу отображается как состояние - см. Изображение карты инцидента

  • Дополнительная панель мониторинга: отображает последние N инцидентов, соответствующих этому событию.

Монитор экземпляра, обозначенный как dashboard.einsatz1einsatzN, периодически опрашивается через кратковременные соединения (без постоянного подключения к панели управления) - см. Панель управления

Конфигурация

В административном интерфейсе экземпляра адаптера настройки сгруппированы по четырем вкладкам: Подключение, Служба восстановления, Описание ключевых слов и Изображение карты инцидента - все четыре вкладки описаны ниже.

Связь

ПолеОписаниеПо умолчанию
URL сервера WAIPБазовый URL экземпляра WAIP-Webhttps://wachalarm.leitstelle-lausitz.de
Время ожидания регистрации (с)Время до регистрации отсутствия подтверждения регистрации10
Задержка переподключения (с)Время ожидания перед ручным переподключением после отключения/ошибки5
Количество инцидентов в историиСколько завершенных инцидентов следует сохранить в einsatzAktuell.json.history (сначала самые последние). Существующие записи, превышающие установленный лимит, удаляются при следующем перезапуске адаптера10
Количество инцидентов в историиСколько завершенных инцидентов хранить в einsatzAktuell.json.history (сначала самые последние). Существующие записи, превышающие установленный лимит, удаляются при следующем перезапуске адаптера10

Интервал поддержания активности сессии не подлежит настройке - он определяется полностью автоматически при каждом обновлении на основе срока действия cookie-файла, сообщаемого сервером (мин. 55 с, макс. 5 мин., соответствует /js/session_keepalive.js на самом сайте).

Зачем нужен сессионный cookie

Сервер WAIP-Web связывает доставку оповещений с сеансовым cookie-файлом Express, который браузер автоматически обновляет каждые несколько минут с помощью встроенного скрипта. Обычный клиент Socket.IO никогда не получает этот cookie-файл автоматически - поэтому адаптер получает его самостоятельно через GET /session/keepalive и прикрепляет к соединению Socket.IO.

Согласно исходному коду WAIP-Web, срок действия cookie-файла настраивается для каждого экземпляра с помощью переменной среды (по умолчанию на сервере: 60 секунд; в данном экземпляре, по-видимому, используется 10 минут) - поэтому фиксированный интервал обновления потенциально был бы некорректным для других экземпляров WAIP-Web. Вместо этого адаптер определяет фактический интервал адаптивно на основе времени истечения срока действия, которое сервер сообщает при каждом вызове (80% от наблюдаемого срока действия, не менее 55 секунд, не более фиксированного 5-минутного предела) - точно такое же ограничение, которое используется в /js/session_keepalive.js на самом сайте.

Спасательная служба

Обрабатывать инциденты службы спасения (флажок администратора, включено по умолчанию): инциденты, einsatzart идентифицирующие их как вызов службы спасения (содержат «Rettung» или «Krankentransport», регистр нечувствительный - см. примеры einsatzart в einsatzAktuell), по умолчанию обрабатываются в обычном режиме, как и в любой предыдущей версии адаптера. Снятие флажка приводит к тому, что адаптер полностью игнорирует такие инциденты: состояния einsatzAktuell.* не обновляются, запись в историю не записывается, объявление TTS не запускается.

  • как будто инцидента и не было. Это существует потому, что

Сообщается, что сообщения о происшествиях, требующих помощи спасательных служб, передаются через систему WAIP только в некоторых регионах/диспетчерских центрах - там, где это не требуется или нежелательно, этот флажок отключает оповещения. Все, что находится ниже этого флажка на вкладке (флажок декодирования и поля с его метками), отображается только пока он отмечен - если он не отмечен, сообщения о происшествиях, требующих помощи спасательных служб, полностью игнорируются, поэтому декодирование их ключевых слов не имеет значения.

einsatzAktuell.stichwort передается с сервера без изменений, как чистый код (например, B2, H:VU mit P) - сам WAIP-Web не объясняет, что это значит, и нет общенационального стандарта: каждый диспетчерский центр использует свой собственный каталог ключевых слов. einsatzAktuell.beschreibung заполняет этот пробел полностью локально, данные никуда не передаются. Эта вкладка является первой из двух проверяемых источников по порядку (см. Описание ключевых слов для второго):

Декодирование службы спасения (флажок администратора, включено по умолчанию): если ключевое слово соответствует шаблону R<RTW-count>N<NEF-count>[p][f][-NT] (например, R1N0 → "Rettungswagen: 1, Notfalleinsatzfahrzeug: 0"), описание генерируется автоматически. Распознаются два варианта написания части p/f/NT: без пробела и с дефисом перед NT (например, R1N1p, R1N0-NT, см. Документированное объяснение Лейтстелле Лаузитц), а также с пробелом и без дефиса (например, R1N1 p, R1N0 nt, как используется IRLS Brandenburg) - эта схема (в любом варианте написания) используется несколькими немецкими диспетчерскими центрами, а не только этими двумя - не имеет эффекта, если ваш диспетчерский центр не использует один из этих шаблонов, поскольку ключевое слово просто не будет соответствовать. Текст для каждой части можно настроить (после включения флажка появляются 5 дополнительных текстовых полей), поскольку адаптер многоязычный, и эти метки не переводятся автоматически:

ЧастьЗначениеМетка по умолчанию
R<n>Количество машин скорой помощи (Rettungswagen)Rettungswagen
p суффиксПолитраумаPolytrauma
f суффиксВключая сотрудников экстренных службFirst Responder
-NT/ nt суффиксСпециальная скорая транспортировкаNotfalltransport mit Notfallkrankenwagen
-NT/ nt суффиксСпециальный санитарный транспортNotfalltransport mit Notfallkrankenwagen

Описание ключевых слов

Проверка выполняется только в том случае, если декодер на вкладке Спасательная служба не совпал со следующим списком строк {keyword pattern, description, match type} - тип совпадения starts with или contains, сравнение нечувствительно к регистру и рассматривает пробелы и дефисы как эквивалентные (любая последовательность любого из них сводится к единице перед сравнением), поэтому, например, H:VU mit P, H:VU-mit-P и H:VU - mit - P соответствуют одной и той же строке - нет необходимости добавлять отдельную строку для каждого варианта написания. Если совпадает несколько строк, автоматически побеждает наиболее специфический (длинный) шаблон - порядок строк не влияет на совпадение, поэтому таблицу можно свободно сортировать по любому столбцу (щелкните заголовок столбца) без изменения поведения. Таблица предварительно заполнена примером списка ключевых слов для пожарной охраны/спасательных служб (B:.../H:...) только в качестве отправной точки - не гарантируется ее соответствие реальному каталогу какого-либо конкретного диспетчерского центра; при необходимости отредактируйте или полностью замените ее. Для резервного копирования или переноса этой таблицы используйте стандартный экспорт/импорт конфигурации экземпляра ioBroker (JSON). После использования этого импорта перезагрузите страницу администрирования перед проверкой этой таблицы - диалоговое окно открытия конфигурации не обновляет ее автоматически из внешнего импорта (это ограничение синхронизации состояния самого компонента таблицы администрирования, а не то, что контролируется этим адаптером).

Если ни эта таблица, ни приведенный выше декодер не совпадают, то einsatzAktuell.beschreibung - это просто null, а не ошибка.

Изображение карты инцидента

Создавать изображение карты для каждого инцидента (флаг администратора, по умолчанию отключен): если включено и инцидент имеет действительные координаты, адаптер загружает необходимые тайлы с общедоступного сервера tile.openstreetmap.org, объединяет их в один PNG-файл, центрированный на местоположении инцидента, и добавляет отметку об авторстве OpenStreetMap (требуемую лицензией ODbL) в нижний левый угол.

По умолчанию область инцидента, которую WAIP-Web отправляет в поле geometry события (обычно это многоугольник в форме круга вокруг местоположения, а не только его центр), отображается на изображении в виде контура с настраиваемым цветом и толщиной - исходная форма, отправленная сервером, а не маркер в его центре. Показать многоугольник области инцидента (флаг администратора, включен по умолчанию) управляет этим: снимите его, чтобы всегда отображать простую точку-маркер в центре, даже если многоугольник доступен. Точка также используется автоматически, если событие вообще не содержит многоугольника (например, только точку) - в этом случае это единственный вариант независимо от флажка. Область инцидента всегда остается полностью видимой при отрисовке многоугольника: если она не помещается на изображении при настроенном уровне масштабирования, адаптер автоматически уменьшает масштаб (никогда не увеличивает) ровно настолько, чтобы поместилась вся область, вместо того, чтобы обрезать ее по краям.

Уровень масштабирования, Цвет маркера и контура и Ширина/высота изображения расположены выше этого флажка, поскольку они применяются к любому режиму отображения: к уровню масштабирования, как описано выше для многоугольника, или как к фиксированному значению для точки маркера; к цвету контура многоугольника или к ядру точки маркера; к ширине/высоте самого изображения в любом случае. Ниже флажка отображается только Толщина контура, поскольку она действительно влияет только на контур многоугольника - размер точки маркера фиксирован и не настраивается.

Путь к файлу записывается в einsatzAktuell.kartenbildPfad (см. einsatzAktuell) - обычно этот файл прикрепляется из скрипта Blockly/JavaScript, например, в качестве вложения к уведомлению Pushover. На диске хранятся только 10 самых последних сгенерированных изображений; более старые автоматически удаляются при каждой записи нового. Обработка тревожных сигналов ожидает завершения обработки изображения, прежде чем продолжить, поэтому гарантируется, что einsatzAktuell.kartenbildPfad уже будет содержать правильное значение к моменту, когда станут доступны остальные поля инцидента (например, einsatzAktuell.alarmAktiv) - но только до настраиваемого тайм-аута OSM: если загрузка/составление плитки не завершено в течение этого времени, регистрируется предупреждение, и einsatzAktuell.kartenbildPfad остается пустым для этого инцидента, не блокируя обработку тревожных сигналов на неопределенный срок.

ПолеОписаниеПо умолчанию
Тайм-аут OSM (с)Максимальное время ожидания изображения (загрузка и компоновка тайла) перед продолжением работы без него (1-60)10
Цвет маркера и контураЦвет центральной точки маркера или контура зоны инцидента, если вместо маркера нарисован многоугольник#DD2020
Ширина изображения (пиксели)Ширина сгенерированного PNG-файла600
Высота изображения (пиксели)Высота сгенерированного PNG-файла400
Высота изображения (пиксели)Высота сгенерированного PNG400
Толщина контура (пиксели)Толщина линии контура в пикселях (1-12)4
Толщина контура (пиксели)Толщина линии контура в пикселях (1-12)4

Изображения хранятся в собственном каталоге данных этого экземпляра адаптера (iobroker-data/<instance>/maps/), а не в виде файловых объектов ioBroker - einsatzAktuell.kartenbildPfad, следовательно, представляет собой реальный абсолютный путь к файловой системе, который скрипт, работающий на том же хосте, может прочитать напрямую. Этот каталог не удаляется автоматически при остановке адаптера или сбросе его конфигурации экземпляра; чтобы удалить его при удалении, установите флажок «Также удалить данные экземпляра» в диалоговом окне подтверждения при удалении экземпляра/адаптера в Admin (доступно начиная с js-controller 4.0 / Admin 5 для любого каталога данных экземпляра адаптера - по умолчанию флажок снят).

Примечание: Используется официальный бесплатный сервер tile.openstreetmap.org, предназначенный для эпизодического/неинтенсивного использования (см. Политика использования тайлов OSM). Одно изображение на инцидент - это вполне допустимо. Не уменьшайте масштаб, чтобы охватить огромные области, и не превращайте это в массовую загрузку тайлов.

Панель управления

Включить панель мониторинга (флаг администратора, по умолчанию выключено): отображает последние N инцидентов, соответствующих настроенному монитору этого экземпляра, как dashboard.einsatz1dashboard.einsatzN, в дополнение к единственному текущему инциденту, уже доступному в einsatzAktuell. Это полезно с идентификатором монитора, ограниченным «всеми диспетчерскими мониторами» (0) или более широким районом/перевозчиком, где одновременно может быть активно несколько инцидентов, и einsatzAktuell.* отображает только самый последний.

В отличие от постоянно активного соединения /waip, которое этот адаптер поддерживает, панель мониторинга обновляется периодически: адаптер получает общедоступную страницу обзора инцидентов /dbrd/, фильтрует ее, отбирая инциденты, соответствующие монитору этого экземпляра (та же корреляция l/a/b/c Leitstelle/Kreis/Träger/Wache, что и в выпадающем списке идентификаторов мониторов - см. Связь), и для каждого из N соответствующих инцидентов по очереди открывает одно кратковременное соединение Socket.IO (никогда не параллельно), чтобы получить его текущее состояние, а затем закрывает его снова. Таким образом, полное обновление в реальности занимает несколько секунд на каждый занятый einsatzN, а не миллисекунды - минимальный интервал обновления, указанный ниже, отражает это.

ПолеОписаниеПо умолчанию
Количество инцидентов для отображенияСколько самых последних соответствующих инцидентов следует отобразить, dashboard.einsatz1einsatzN (1-20)10
Интервал обновления (с)Как часто обновляется панель мониторинга (30-300)60

Обновление также выполняется один раз сразу после каждого (пере)запуска адаптера (чтобы панель мониторинга не оставалась пустой в течение заданного интервала), и один раз при получении нового сигнала тревоги для собственного монитора этого экземпляра (einsatzAktuell.*) - в дополнение к обычному таймеру. Ручное обновление можно запустить в любое время с помощью состояния кнопки dashboard.refreshNow, например, с помощью кнопки VIS или скрипта.

Изображения карт, обозначенные как dashboard.einsatzN.kartenbildPfad, не генерируются отдельно для панели мониторинга - они ищутся в той же истории файлов, которую Изображение карты инцидента уже создает для собственного монитора этого экземпляра. einsatzN имеет изображение карты только тогда, когда этот адаптер уже сгенерировал его для этого конкретного инцидента с помощью собственной обработки тревожных сигналов einsatzAktuell.* - наиболее полная обработка происходит, когда идентификатор монитора равен 0 (все диспетчерские мониторы) и включена опция Генерировать изображение карты для каждого инцидента, поскольку в этом случае каждый инцидент, который может появиться на панели мониторинга, также прошел через einsatzAktuell.* хотя бы один раз. При более узком идентификаторе монитора записи einsatzN для инцидентов вне собственной истории тревожных сигналов этого монитора не будут иметь изображения карты - это ожидаемое поведение, а не ошибка.

Отключение этой функции удаляет всё дерево объектов dashboard.* (каналы и состояния, а не только их значения); уменьшение количества отображаемых инцидентов удаляет только теперь неиспользуемые записи einsatzN в конце (например, изменение с 10 на 5 удаляет dashboard.einsatz6einsatz10). Оба изменения вступают в силу только при следующем перезапуске адаптера после сохранения (ioBroker перезапускает экземпляр при любом изменении конфигурации - удаление не происходит мгновенно, пока открыто диалоговое окно администратора).

Штаты (в соответствии с waip-web.0.*)

Обратная связь и маршруты представляют собой списки 1:n для каждого инцидента. Они хранятся в виде плоских JSON-массивов в einsatzAktuell.json.* (без вложенных объектов/массивов внутри строки), поэтому их можно напрямую привязать к виджетам таблиц VIS - дополненных быстро привязываемыми счетчиками, так что для привязок и триггеров вообще не требуется разбор JSON.

Информация

ШтатТипОписание
connectionлогическое значениеСтандартный индикатор ioBroker: соединение с сервером WAIP активно

Статус

ШтатТипОписание
connectedлогическое значениеТехнически установлено соединение Socket.IO
registeredMonitorNameстрокаОтображаемое имя этого монитора без идентификатора (например, "Leitstelle: Lausitz"); определяется один раз при запуске с той же страницы обзора /waip/, что и выпадающее меню администратора, null, если его не удалось определить
registrationAcceptedлогическое значениеtrue после получения первого события, false сразу после подключения или по истечении времени ожидания регистрации
registrationPendingлогическое значениеtrue сразу после подключения, пока ожидается ответ от сервера, false после принятия или истечения времени ожидания
registrationPendingлогическое значениеtrue сразу после подключения, пока ожидается ответ от сервера, false после принятия или истечения времени ожидания

EinsatzAktuell

Плоские поля текущего инцидента. Очищено (null/0) на io.standby, что соответствует официальному интерфейсу - alarmAktiv, следовательно, является надежным переключателем, указывающим, содержат ли эти поля в данный момент реальные данные. Последний завершенный инцидент остается доступным через einsatzAktuell.json.history:

Примечание: Адаптер всегда отображает только самый последний активный инцидент (einsatzAktuell.* / einsatzAktuell.json.current) - > соответствующий монитору оповещений официального интерфейса WAIP-Web. В принципе, в WAIP-Web может быть одновременно активно несколько инцидентов (например, два оповещения, поступающие с небольшим интервалом). Эти состояния не являются массивом одновременно работающих инцидентов - они перезаписываются каждым новым событием io.new_waip, поэтому второй инцидент, работающий параллельно, в настоящее время не виден через этот адаптер. Полный обзор всех активных в данный момент инцидентов доступен только через панель управления подключенного экземпляра WAIP-Web.

Примечание: Сервер WAIP-Web заполняет только einsatznummer, objekt/ > objektteil, besonderheiten, strasse/hausnummer, > einsatzdetails и флаг разрешения для включенных клиентов > (db_user_check_permission_for_waip() в собственном > server/waip.js сервера) - поскольку этот адаптер подключается без авторизации по своей конструкции (см. Об этом адаптере), сервер > всегда отправляет эти пустые значения/false. Поэтому они вообще не отображаются как состояния, а вместо этого навсегда содержат мертвые значения.

ШтатТипОписание
alarmAktivлогическое значениеtrue с момента последнего io.new_waip, false с момента последнего io.standby
idномерВнутренний идентификатор инцидента
uuidстрокаУникальный UUID инцидента (также используется для привязки обратной связи)
einsatzartстроканапример «Brandeinsatz» (пожар), «Hilfeleistungseinsatz» (техническая помощь), «Rettungseinsatz» (спасение/скорая помощь), «Krankentransport» (транспортировка пациентов)
stichwortстрокаКлючевое слово тревоги
beschreibungстрокаОписание для stichwort, определено локально (не отправлено сервером) - см. Служба спасения/[Описание ключевых слов] ниже. null если ничего не найдено
ortстрокаМестоположение/город
ortsteilстрокаРайон (если отличается от ort)
alarmierungszeitстрока (дата)Время будильника
ablaufzeitстрока (дата)Окончание времени отображения в режиме ожидания, основание для restzeit
sondersignalномер1 = специальный сигнал (фары и сирена), в противном случае - нет
latitude / longitudeномерМестоположение инцидента (нормализовано по полям wgs84 или центроиду GeoJSON)
kartenbildPfadстрокаПуть к последнему сгенерированному изображению карты инцидентов (PNG) - см. Изображение карты инцидента. Пустое до тех пор, пока не будет готово первое изображение для текущего инцидента; также очищается (остается пустым) в начале нового инцидента, если генерация не удалась или не завершилась в течение времени ожидания OSM, и - как и другие поля выше - при io.standby. Сам файл изображения не удаляется при очистке состояния (удаляются только файлы, хранящиеся в течение 10 дней, см. [Изображение карты инцидента])
routenGesamtномерКоличество маршрутов в текущем инциденте
rueckmeldungenGesamtчислоОбщее количество отзывов по текущему инциденту
rueckmeldungen.rollen.ekномерОбратная связь учитывается как член команды («Einsatzkraft»)
rueckmeldungen.rollen.gfномерОбратная связь засчитывается как командир экипажа («группенфюрер»)
rueckmeldungen.rollen.zfномерОбратная связь учитывается как начальник отдела («Цугфюрер»)
rueckmeldungen.rollen.vfчислоОбратная связь учитывается как у командира группы ("Verbandsführer")
rueckmeldungen.funktionen.agtномерУчет обратной связи с аттестацией дыхательного аппарата («Atemschutzgeräteträger»)
rueckmeldungen.funktionen.fzfномерОтзыв засчитывается как командир машины («Фарцойгфюрер»)
rueckmeldungen.funktionen.maчислоОтзывы учитываются как отзывы водителя/оператора ("машиниста")
rueckmeldungen.funktionen.medчислоКоличество отзывов с медицинской квалификацией
rueckmeldungen.funktionen.medчислоКоличество отзывов с медицинской квалификацией

EinsatzAktuell.json

Плоские JSON-объекты/массивы, максимум на один уровень вложенности, предназначены для прямой привязки к виджетам таблиц VIS (вложенные структуры, такие как простой объект {routen, rueckmeldungen, ...}, обычно не отображаются этими виджетами). routen/rueckmeldungen/emAlarmiert/emWeitere содержат только данные текущего инцидента - они очищаются ([]) при io.standby и не являются частью истории. Как и в случае с einsatzAktuell.* выше, current содержит только самый последний активный инцидент - см. примечание в разделе einsatzAktuell.

ШтатТипОписание
currentстрока (массив JSON)Плоские данные текущего инцидента: те же 12 полей, что и в отдельных состояниях einsatzAktuell.* выше (idsondersignal, плюс beschreibung, alarmierungszeit, lat/lon), плюс registeredMonitor/registeredMonitorName (монитор, к которому адаптер был зарегистрирован в тот момент), объединенные в один объект внутри одноэлементного массива ([], если нет активного инцидента) - обертка массива необходима, потому что большинство виджетов таблиц требуют массив в корне, а не простого объекта
routenстрока (массив JSON)Маршруты текущего инцидента; каждая запись содержит nr_wache, name_wache, color, lat, lon (position преобразуется в плоский lat/lon - см. примечание ниже о том, что представляет собой lat/lon для маршрута)
rueckmeldungenстрока (массив JSON)Записи обратной связи по текущему инциденту, полученные с сервера
emAlarmiertстрока (массив JSON)Ресурсы, получившие оповещения по текущему инциденту; каждая запись содержит name, zeit, wache, zeit_alarmierung_iso, zeit_ausgerueckt_iso
emWeitereстрока (массив JSON)Дополнительные ресурсы текущего инцидента, той же формы, что и emAlarmiert
emWeitereстрока (массив JSON)Дополнительные ресурсы текущего инцидента, той же формы, что и emAlarmiert

Примечание: routen[].lat/.lon - это местоположение станции, получившей оповещение, а не точка на фактическом маршруте движения и не место происшествия. Сервер отправляет каждый маршрут либо как полный LineString (рассчитанный путь от станции до места происшествия), либо, если путь рассчитать не удалось, как одну пару координат для самой станции - в обоих случаях адаптер преобразует lat/lon в местоположение станции (первая точка линии в случае LineString) для обеспечения согласованного значения для всех записей. Полная геометрия маршрута не отображается как состояние.

EinsatzAktuell.tts

Голосовое объявление (io.playtts) для текущего инцидента - находится в канале einsatzAktuell, а не в отдельном канале верхнего уровня, поскольку не имеет смысла без инцидента. История отсутствует: объявление TTS имеет значение только в данный момент, поэтому сохраняется только самое последнее.

ШтатТипОписание
lastстрока (URL)Полный абсолютный URL-адрес файла mp3 последнего голосового объявления. Сервер отправляет только простой (часто относительный) путь, предназначенный для использования в качестве audio.src в браузере, имеющем тот же источник; адаптер преобразует его в URL-адрес, настроенный для сервера WAIP, поэтому ссылка также работает за пределами веб-страницы WAIP (например, в аудиовиджете VIS)
lastTimestampстрока (дата)Время последнего объявления

Панель управления

Присутствует только при включении Панель управления - см. там информацию о жизненном цикле дерева объектов при включении/отключении/изменении размера. dashboard.einsatzN (N = 1 … заданное количество отображаемых инцидентов) имеет ту же форму, что и einsatzAktuell/einsatzAktuell.json выше, для N-го по счету последнего инцидента, соответствующего монитору этого экземпляра - не ограничивается единственным текущим инцидентом. Все поля занятого einsatzN всегда перезаписываются при каждом обновлении (а не только при изменении), поэтому постоянная обратная связь для инцидента, который остается на том же уровне einsatzN при каждом обновлении, продолжает обновляться; В незанятом поле einsatzN (меньшее количество соответствующих инцидентов, чем настроено) все поля имеют пустые значения, точно так же, как в поле einsatzAktuell.*, когда нет активных инцидентов.

Намеренно без restzeit/ablaufzeit (данные /dbrd/ инцидента в WAIP-Web не имеют эквивалентного поля, в отличие от потока тревожных сигналов в реальном времени /waip) и без эквивалента einsatzAktuell.tts (в пространстве имен /dbrd нет события TTS). dashboard.einsatzN.json.wachen не имеет аналога einsatzAktuell.json.* в обратном порядке - он берется из поля (wachen[], участвующие станции инцидента), которое включается только в полезную нагрузку /dbrd.

ШтатТипОписание
refreshNowлогическое значение (кнопка)Напишите true, чтобы запустить немедленное обновление панели мониторинга, например, с помощью кнопки VIS или скрипта. Сбрасывается до false после завершения обновления
einsatzN.idномерВнутренний идентификатор инцидента
einsatzN.uuidстрокаУникальный UUID инцидента
einsatzN.einsatzartстрокаТо же значение, что и einsatzAktuell.einsatzart
einsatzN.stichwortстрокаКлючевое слово тревоги
einsatzN.beschreibungстрокаОписание для stichwort, разрешается так же, как и einsatzAktuell.beschreibung
einsatzN.ortстрокаМестоположение/город
einsatzN.ortsteilстрокаРайон (если отличается от ort)
einsatzN.alarmierungszeitстрока (дата)Время будильника
einsatzN.sondersignalномер1 = специальный сигнал (фары и сирена), в противном случае - нет
einsatzN.latitude / einsatzN.longitudeномерМесто происшествия, та же нормализация, что и в einsatzAktuell
einsatzN.kartenbildPfadстрокаПуть к соответствующему, ранее сгенерированному изображению карты инцидента - см. Панель управления выше. Пусто, если изображение не найдено
einsatzN.routenGesamtномерКоличество маршрутов для инцидента einsatzN
einsatzN.rueckmeldungenGesamtчислоОбщее количество отзывов по инциденту einsatzN
einsatzN.rueckmeldungen.rollen.* / .funktionen.*числоТе же восемь счетчиков обратной связи, что и в einsatzAktuell.rueckmeldungen, согласно einsatzN
einsatzN.json.currentстрока (массив JSON)einsatzN - плоские данные об инциденте, той же формы, что и einsatzAktuell.json.current (без registeredMonitor/registeredMonitorName)
einsatzN.json.routenстрока (массив JSON)Маршруты инцидента einsatzN, той же формы, что и einsatzAktuell.json.routen
einsatzN.json.rueckmeldungenстрока (массив JSON)Отзывы об инциденте einsatzN
einsatzN.json.emAlarmiertстрока (массив JSON)Ресурсы, получившие оповещение об инциденте einsatzN
einsatzN.json.wachenстрока (массив JSON)Станции, участвовавшие в инциденте einsatzN (em_station_id/em_station_name) - доступны только через /dbrd, аналога для einsatzAktuell.json.* нет
einsatzN.json.wachenстрока (массив JSON)Станции, участвующие в инциденте einsatzN (em_station_id/em_station_name) - доступны только через /dbrd, без аналога einsatzAktuell.json.*

Отладка

ШтатТипОписание
lastEventстрока (массив JSON)Последнее полученное событие сокета (имя + метка времени), для диагностики соединения; массив из одного элемента ([], если еще не было), для совместимости с виджетом таблицы VIS
rawPayloadShortстрокаПредварительный просмотр (500 символов) необработанного, ненормализованного полезного содержимого io.new_waip
ignoredCountчислоКоличество отброшенных событий (полезная нагрузка явно указана с другим идентификатором монитора)
monitorAuditстрока (массив JSON)Хронологический журнал событий подключения/регистрации/повторного подключения (200 записей)
sessionExpiresстрока (дата)Время истечения срока действия сессионного cookie на момент последнего обновления
lastErrorстрокаПоследнее сообщение об ошибке, сообщенное сервером (io.error); обычный текст, а не JSON, поскольку сервер отправляет это как обычную строку
serverVersionстрокаПоследний зарегистрированный идентификатор экземпляра сервера (io.version); изменение указывает на необходимость перезапуска сервера
serverVersionstringПоследний зарегистрированный идентификатор экземпляра сервера (io.version); изменение указывает на перезапуск сервера

Ведение журнала

Весь текст логов на английском языке. Повторяющиеся сбои (обновление cookie-сессии, регистрация WAIP, соединение Socket.IO, поток событий от неправильного монитора) регистрируются один раз в warn при первом возникновении, затем в debug, пока они сохраняются, и один раз в info при восстановлении - в соответствии с Официальные правила ведения логов ioBroker.

См. LOGGING.md для получения полной информации обо всех сообщениях журнала, которые может создавать адаптер, сгруппированных по уровню, с указанием причины и примером.

Changelog

WORK IN PROGRESS

  • registrationTimeoutSec and reconnectDelaySec are now clamped in code to their admin UI range (1-120s), matching how every other numeric configuration value (e.g. historySize, mapImageWidth) was already handled - a direct instance config JSON edit/import can no longer set them outside that range.
  • The stateChange listener (used only for dashboard.refreshNow) is now registered only while the Dashboard feature is enabled, matching its subscribeStates() call, instead of unconditionally in the constructor.

1.0.0 (2026-08-30)

  • Breaking change: the einsatz channel is renamed to einsatzAktuell (to distinguish it from the dashboard.einsatz1einsatzN dashboard channels), and einsatzAktuell.json.history10 is renamed to einsatzAktuell.json.history, now holding a configurable number of entries (new "Number of incidents in history" setting on the Connection tab, 1-100, default 10). Update any VIS bindings/scripts referencing the old einsatz.*/einsatz.json.history10 paths - they are removed automatically on upgrade, along with their values.
  • Dashboard channel/state display names are now consistent: they use "Einsatz N" throughout, matching the einsatzAktuell.* naming, and the redundant "flat JSON array" phrase was removed from every state name. Object IDs are unaffected, only the display names shown in Admin/VIS.

0.12.1 (2026-08-30)

  • Fixed the Dashboard admin config: the tab was mistranslated as "Armaturenbrett" (car dashboard) in German instead of "Dashboard", its help texts used wrong/mistranslated terms ("Versandzentrum"/"Vorfall" instead of "Leitstelle"/"Einsatz"), and the refresh interval label was missing its "(s)" unit suffix.
  • Fixed routen[].lat/.lon (both einsatz.json.routen and dashboard.einsatzN.json.routen): previously resolved to the geometric bounding-box center of the entire route line - a point with no real meaning, since it lies "somewhere along the way" rather than at any actual location. Now resolves to the alerted station's own location instead (the first point of the route line, matching a separate coordinate-pair format the server sends when no route could be calculated for a station). Also fixed dashboard.einsatzN.json.routen specifically: it was missing the same geo normalization einsatz.json.routen already applied, so a route's raw, unresolved geometry (dozens of coordinate pairs) or the raw fallback coordinate field ended up in the written JSON instead of flat lat/lon.

0.12.0 (2026-08-28)

  • New optional Dashboard feature: mirrors the last N incidents matching this instance's monitor as dashboard.einsatz1einsatzN (off by default). Uses short-lived Socket.IO connections to WAIP-Web's /dbrd namespace polled on a configurable interval, not a permanent connection - see Dashboard and dashboard states for the full behavior, including the manual refresh button and the object-deletion behavior when disabling the feature or reducing the number of incidents to show.

0.7.38 (2026-08-27)

  • Fixed a race condition where a routes update (io.routes) or TTS announcement (io.playtts) arriving while an incident was being finalized could still repopulate einsatz.json.current, einsatz.json.routen and einsatz.routenGesamt for the already finished incident. The 0.7.37 guard checked a flag that was only cleared at the very end of the finalization, leaving a window open across several await points.
  • Fixed lost entries in debug.monitorAudit: the log was written with an unsynchronized read-modify-write, so two entries created within milliseconds of each other (e.g. connect_called followed by emit_WAIP) could overwrite one another. Writes are now serialized.
  • Fixed configuration values falling back to the minimum instead of the default when a numeric admin field is left empty - an empty zoom field produced zoom 1 (the whole world map) instead of the configured default, and an empty width field produced 100px instead of 600px.
  • Added a unit test suite (npm run test:unit, 75 tests) covering the geo normalization, the keyword decoder/table, the monitor matching and the state-definition consistency. npm test now runs it alongside the package tests.

0.7.37 (2026-08-26)

  • Fixed a bug where a routes update (io.routes) or TTS announcement (io.playtts) arriving after an incident had already ended (io.standby) could revive einsatz.json.current/.routen/ einsatz.routenGesamt or einsatz.tts.last/.lastTimestamp for the already-finished incident, while every other einsatz.* field correctly stayed cleared. Both handlers now ignore such events while no incident is active.

Older entries have been moved to CHANGELOG_OLD.md.

License

MIT License (this adapter) – see LICENSE.

The adapter connects to instances of WAIP-Web, which is licensed under CC BY-SA 4.0 by Robert-112. This adapter contains no code from that project.

Copyright (c) 2026 rnc11

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.