Адаптер ioBroker для камер умного дома Bosch (Eyes Outdoor, 360 Indoor, Gen2 Eyes Indoor II + Outdoor II). Полный набор основных функций работает от начала до конца и проверен в режиме реального времени на реальном оборудовании.
Поддерживаемые модели: Eyes Outdoor (Gen1), Eyes Outdoor II (Gen2), 360 Indoor (Gen1), Eyes Indoor II (Gen2) — настройка времени и параметров для каждой модели выполняется автоматически.
Официального API нет. Этот адаптер использует API Bosch Cloud, полученный путем обратного проектирования и обнаруженный с помощью анализа трафика mitmproxy в официальном приложении Bosch Smart Camera.
Оглавление
- Сравнение вариантов интеграции — выберите подходящий проект для вашей платформы.
- Подключение к сети — необходимые порты, проблемы с VLAN/подсетями.
- RTSP Front-Door без учетных данных — флагманская функция, блок-схема и конфигурация.
- Список изменений
- Лицензия
Сравнение интеграций
API, полученный методом обратного проектирования для умных домашних камер Bosch, доступен через четыре дочерних проекта. Выберите тот, который подходит для вашей платформы.
| Особенность | Интеграция с Home Assistant | Инструмент командной строки Python | ioBroker Adapter | Сервер MCP | Фронтенд (NiceGUI) | Node-RED |
|---|---|---|---|---|---|---|
| Зрелость | v15.0+ — Шкала качества HA Platinum | v10.12+ стабильная версия (Mini-NVR BETA) | v1.8+ стабильная версия · npm | v1.7+ стабильная версия · PyPI | v0.4.0 alpha · PyPI | v0.4.0 alpha · npm |
| Платформа | Домашняя помощь (HACS) | Автономный интерфейс командной строки Python 3.10+ | ioBroker (npm) | Python 3.10+ · pipx / uvx · stdio + streamable-HTTP для клиентов MCP (Claude Desktop, Claude Code, пользовательские) | Веб-приложение NiceGUI · Python 3.10+ | Палитра Node-RED · npm |
| Авторизоваться | OAuth2 PKCE (браузер) | OAuth2 PKCE (браузер) | OAuth2 PKCE (браузер) | ◑ акции CLIbosch_config.json | ◑ акции CLIbosch_config.json | ◑ токен обновления из командной строки |
| Снимки | ✅ РоднойCamera.image | ✅snapshot команда | ✅ Файловое хранилище + base64 DP | ✅bosch_camera_snapshot (Только по локальной сети) | ✅ Прямая трансляция + резервный вариант мероприятия | ✅snapshot узел |
| Прямая трансляция RTSP (по локальной сети) | ✅ через компонент HA Stream | ✅ вывод ffmpeg/RTSPS | ✅ TLS-прокси → локальный RTSP | ✅bosch_camera_stream_url (Только локальная сеть, без облачного ретранслятора) | ◑ внутренний (go2rtc) | ◑stream-url узел (только URL) |
| WebRTC (задержка менее секунды) | ✅ через интегрированный go2rtc | ✅ (v10.6.0)live --webrtc | ❌ | ❌ | ✅ через go2rtc (или снимок) | ❌ |
| URL с двумя потоками (основной + подпоток) | ✅sensor.bosch_<n>_stream_url +_sub (v12.4.0, включение по желанию для каждой камеры) | ✅info показывает оба ·live --sub (v10.5.0) | ✅stream_url +stream_url_sub (v0.5.3 экспериментальная версия) | ◑bosch_camera_stream_url — только для основного потока | ❌ (только для субтрансляции) | ◑ Только URL — без возможности добавления подзаголовков |
| Внешний регистратор (BlueIris, Frigate) | ✅ через go2rtc | ✅ стандартная труба | ✅ URL-адрес для дайджест-кредитов + опция привязки к локальной сети | ✅ URL возвращен, передача управления осуществляется ffmpeg / go2rtc. | ❌ | ◑stream-url → провод ниже по потоку |
| режим конфиденциальности | ✅ переключить сущность | ✅ команда | ✅ DP | ✅bosch_camera_privacy_set (резервный вариант по локальной сети черезprefer_local ) | ✅ переключить | ✅privacy узел |
| Передний прожектор (1-е/2-е поколение) | ✅ световое существо | ✅ команда | ✅ DP | ✅bosch_camera_light_set (Резервное копирование по локальной сети) | ❌ (Заготовка 2-го этапа) | ✅bosch-camera-light node (v0.3.0-alpha) |
| RGB-подсветка для стен (Gen2 Outdoor II) | ✅ Подсветка с RGB | ◑ Только включение/выключение — без RGB | ✅ Цвет + Яркость DP | ❌ (только включение/выключение — RGB не отображается) | ❌ | ◑ Включение/выключение + только интенсивность — без RGB (v0.3.0-alpha) |
| Сирена тревожной сигнализации | ✅ Кнопочный узел (Gen2 Indoor II) | ✅ команда (только для Gen2 Indoor II) | ✅ DP | ✅bosch_camera_siren_trigger (Только для Gen2 Indoor II) | ✅ триггер + длительность (только для Gen2 Indoor II) | ❌ |
| Обновление прошивки | ✅ Обновить сущность + Исправить процесс исправления, кнопка установки (v14.4.10) | ✅ статус + установка (v10.11.0) | ✅ Состояния прошивки + триггер установки, защита от блокировки записи (v1.8.0) | ✅ Статус + инструменты установки (v1.7.0) | ◑ Отображение состояния только для чтения, установка невозможна | ✅ статус + установка узлов (v0.4.0-alpha) |
| Поворот изображения на 180° | ✅ переключатель | ❌ | ✅ DP | ❌ | ❌ | ❌ |
| События, связанные с движением / человеком / звуком | ✅ Передача FCM + резервный вариант опроса | ◑watch Только команды (команда событий удалена) | ✅ Передача FCM + резервный вариант опроса | ✅bosch_camera_events (запрос по требованию) | ◑ Таблица событий, доступных только по запросу | ✅event узел (опрос) |
| Состояние срабатывания по фронту движения | ✅binary_sensor.motion | н/д | ✅motion_active DP (v0.5.3) | н/д (запрос-ответ, без подписки) | ❌ | ❌ |
| Автоматический снимок при движении | ✅ Обновляет объект «Камера» | н/д | ✅ пишетlast_event_image base64 (v0.5.3) | н/д (нет фонового цикла) | ❌ | ❌ |
| Синтетический триггер движения (внешний датчик) | ✅ сервис | н/д | ✅ DP | ❌ | ❌ | ❌ |
| Зоны движения / маски конфиденциальности | ✅ чтение + запись | ✅ чтение + запись | ✅ чтение + запись (v1.8.0) | ✅ получить / установить / очистить (v1.7.0) | ❌ (визуального редактора пока нет) | ❌ |
| Правила/расписания автоматизации | ✅ чтение + запись | ✅ чтение + запись | ✅ Полная поддержка CRUD (v1.8.0) | ✅ Список / Добавить / Редактировать / Удалить (v1.7.0) | ✅ Полное управление CRUD (добавление/добавление/редактирование/удаление) | ❌ |
| График освещения | ✅ чтение (запись через сервис, только для Gen1 Eyes Outdoor) | ✅ чтение + запись | ✅ читать (только для первого поколения, версия 1.2.0) | ✅ получить / установить (v1.7.0) | ✅ Чтение + запись (камеры Outdoor Eyes) | ❌ |
| Загрузка клипов из облака (история ~30 дней) | ✅ через медиабраузер | ❌ | ❌ (припарковано — пока нет запроса от сообщества) | ❌ (намеренно не показано — большие грузы) | ❌ (используйте командную строку) | ◑clip_url в полезной нагрузке события |
| Мини-видеорегистратор (локальная запись) | ✅ Непрерывная + буферизованная по событиям, кольцевая буферная преролл-заставка (режимы v11.2.0 BETA → v14.7.0) | ◑ Мультиплексирование сегментов, запускаемое событием, без кольца предварительной загрузки (v10.7.0 BETA) | ❌ (передаёт данные внешнему регистратору через RTSP-конечную точку без учётных данных) | ❌ (без концепции NVR) | ◑ Только непрерывный режим, без буферизации событий (v0.4.0-alpha) | ◑ непрерывный только черезbosch-camera-nvr-record node (v0.4.0-alpha) |
| Загрузка клипа через SMB/NAS | ✅ | ✅ (v10.7.0 BETA) | ❌ | ❌ | ❌ | ❌ |
| Совместное использование камеры (друзьями) | ✅ Услуги (поделиться / пригласить / составить список) | ✅ команда | ✅ поделиться / пригласить / удалить (только для Gen2, версия 1.8.0) | ✅ список / пригласить / поделиться / отменить доступ / удалить (v1.7.0) | ✅ список/пригласить/удалить/поделиться/отменить доступ | ❌ |
| Панорамирование/наклон (360° Gen1) | ✅ услуги | ✅ команда | ✅pan_position ДП | ✅bosch_camera_pan | ✅ Слайдер подключен к API в реальном времени | ❌ |
| Названия предустановок панорамирования (домой / влево / вправо / назад влево / назад вправо) | ✅ Выберите организацию, которая согласится на участие | ✅pan --preset флаг | ✅pan_preset ДП | ✅bosch_camera_pan preset= | ❌ | ❌ |
| Двусторонняя аудиосвязь / домофон | ❌ | ✅ команда | ❌ | ◑ только для прослушиванияbosch_camera_intercom_open (v1.7.0) | ❌ | ❌ |
| Доставка веб-хуков для событий | ✅ Сервис + варианты подписки | ✅watch --webhook URL | ✅ через мост MQTT | ❌ (модель «запрос-ответ») | ❌ | ❌ |
| Мост событий MQTT (движение / звук / человек) | н/д (собственная шина событий HA) | н/д (однократный запуск) | ✅ admin-config | н/д | ❌ | ❌ |
| Apple HomeKit (через мост HA Core) | ✅ документировано | н/д | н/д | н/д | н/д | н/д |
| Планировщик моментальных снимков / замедленная съемка | ✅ примеры/YAML | ✅ Примеры использования cron + ffmpeg | ✅ Пример Blockly | н/д | ❌ | ❌ |
| Встроенная карточка/виджет панели управления | ✅ 2 карты Lovelace (одна + сетка) | н/д | ✅ 2 виджета vis-2 — BoschCamera + BoschOverview многокамерная система | н/д | ✅ (сама по себе является веб-панелью управления) | ❌ |
| Режим «картинка в картинке» сохраняется во вкладке, работающей в фоновом режиме. | ✅hass-suspend-when-hidden keep-alive (v14.0.0) | н/д (без пользовательского интерфейса) | ✅ Собственная функция PiP + восстановление после зависания, пульсация Web-Worker (v1.7.2/v1.7.3) | н/д (без пользовательского интерфейса) | ✅ reconnect-timeout + freeze-recovery (v0.4.0-alpha) | н/д (без пользовательского интерфейса) |
| Резервный вариант удаленного облачного ретранслятора | ✅ Автоматическое переключение при недоступности локальной сети | ✅ удаленный режим | ❌ (Предназначено только для местного рынка) | ❌ (Только по локальной сети; статус/события через облако) | ◑ наследует интерфейс командной строки | ◑ Дистанционное управление (ручное) |
| Интерфейс администратора/конфигурации на основе браузера | ✅ Схема конфигурации высокой доступности | н/д (CLI) | ✅ Вкладки JSON-конфигурации | н/д (с использованием LLM; настройка через CLI / MCP-клиент) | ✅ Страница настроек | ◑ узел конфигурации редактора |
| Языки пользовательского интерфейса | EN · DE · FR · ES · IT · NL · PL · PT · RU · UK · ZH-Hans (v12.4.0) | EN · DE · FR · ES · IT · NL · PL · PT · RU · UK · ZH-Hans (v10.3.0) | EN · DE · FR · ES · IT · NL · PL · PT · RU · UK · ZH-CN | н/д (нет пользовательского интерфейса — LLM является фронтендом) | ◑ интернационализация бэкэнда · пользовательский интерфейс преимущественно на английском языке | н/д (только на английском языке) |
Условные обозначения: ✅ поддерживается · ❌ не поддерживается / не планируется · н/д — неприменимо для данной платформы.
Все четыре проекта используют один и тот же метод обратного проектирования — Cloud API + протокол RCP, — но развиваются независимо. Интеграция с Home Assistant представляет собой наиболее полную эталонную реализацию; интерфейс командной строки на Python — это самый низкоуровневый/скриптовый интерфейс; адаптер ioBroker ориентирован на панели мониторинга VIS и автоматизацию Blockly; сервер MCP предоставляет клиентам MCP (Claude Desktop, Claude Code, пользовательские) тщательно разработанный, ориентированный на локальную сеть интерфейс инструментов для управления камерой на естественном языке.
Поддерживаемые камеры
Поддерживаются все четыре существующие модели камер Bosch Smart Home .
| Камера | Поколение | Тип | Обнаружен кодек/прошивка | Основные моменты |
|---|---|---|---|---|
| 360° В помещении | Поколение 1 | В помещении | H.264 + AAC · FW 7.91.x | Поворотно-наклонный мотор, автоматическое слежение, ИК-ночное видение, механическая защитная шторка. |
| Глаза в помещении II | Gen2 | В помещении | H.264 + AAC · FW 9.40.x | Встроенная сирена 75 дБ, функция Audio+ для обнаружения разбития стекла / дыма / угарного газа, режим обнаружения ЗОН, RGB-светодиоды, выдвижная головка (аппаратная кнопка конфиденциальности). |
| Глаза на улице | Поколение 1 | Для наружного применения (IP66) | H.264 + AAC · FW 7.91.x | Фронтальный прожектор, подсветка с датчиком движения, датчик освещенности, подсветка по расписанию. |
| Глаза на открытом воздухе II | Gen2 | Для наружного применения (IP66) | H.264 + AAC · FW 9.40.x | Группы RGB-светодиодов спереди, сверху и снизу, DualRadar (движение + вторжение), режим подсветки стен, параметр высоты установки. |
Отказ от ответственности
Этот проект представляет собой независимый адаптер, разработанный сообществом. Он не связан с компанией Robert Bosch GmbH, не одобрен ею и не имеет к ней никакого отношения. «Bosch» и «Bosch Smart Home» являются зарегистрированными товарными знаками компании Robert Bosch GmbH.
Данный адаптер взаимодействует с API, полученным методом обратного проектирования и не имеющим документации. Предоставляется «как есть» , без каких-либо гарантий. Используйте на свой страх и риск. API может быть изменен или отключен компанией Bosch в любое время. Обратное проектирование было выполнено исключительно в целях обеспечения совместимости в соответствии с § 69e Закона Германии об авторском праве (UrhG) и Директивой ЕС 2009/24/EC .
Настраивать
⚠ Код авторизации Bosch в URL-адресе перенаправления истекает примерно через 60 секунд. Откройте диалоговое окно администратора адаптера в одной вкладке ПЕРЕД тем, как нажать кнопку входа, чтобы вы могли вставить URL-адрес обратно, как только Bosch перенаправит вас. Если код истечет, просто снова нажмите «Открыть вход в Bosch в браузере» — каждый раз будет генерироваться новый URL-адрес.
- Установите адаптер и создайте экземпляр (адаптер запускается в режиме "ожидание входа в систему").
- Откройте диалоговое окно администрирования адаптера (Экземпляры → bosch-smart-home-camera → значок гаечного ключа). На вкладке «Подключение» отображается процесс входа в систему; оставьте это диалоговое окно открытым в одной вкладке.
- Нажмите «Открыть Bosch Login в браузере» — в новой вкладке откроется Bosch SingleKey ID. Войдите в систему (при необходимости введите капчу/многофакторную аутентификацию).
- Bosch перенаправляет ваш браузер на
https://www.bosch.com/boschcam?code=…&state=…Страница может отображаться пустой или с ошибкой 404 — это нормально. Немедленно скопируйте полный URL-адрес из адресной строки. - Вернитесь на вкладку «Администрирование» адаптера и вставьте URL-адрес в поле «Вставленный URL-адрес обратного вызова», затем сохраните. Сделайте это в течение примерно 60 секунд после перенаправления, иначе код авторизации истечет, и вам придется начать все сначала.
- Адаптер перезапускается, обменивает код авторизации на токены, получает данные с ваших камер и запускает прослушиватель FCM. При последующих перезапусках этап обновления через браузер будет пропущен, если сохраненный токен обновления все еще действителен.
В случае недоступности кнопки "Администратор" (очень старые версии ioBroker Admin) адаптер также публикует URL-адрес для входа в систему в виде объекта состояния — open.Objects → bosch-smart-home-camera.0 → info → login_url и нажмите на значение, чтобы перейти к авторизации. Шаг перенаправления и вставки остается тем же.
Если срок действия кода авторизации истечет (вы это увидите).code expired (в логе после вставки), не паникуйте — просто снова нажмите «Открыть вход в Bosch в браузере». Адаптер генерирует новый URL-адрес каждый раз, когда вы нажимаете кнопку.
Если токен обновления будет отклонен (после смены пароля Bosch или длительного простоя), адаптер зарегистрирует новый URL-адрес для входа, и вам нужно будет повторить шаги 3–5.
Процесс авторизации OAuth2 PKCE
sequenceDiagram
autonumber
participant U as User (browser)
participant A as ioBroker Adapter
participant B as Bosch SingleKey ID
A->>A: generate PKCE verifier + state
A->>U: log login URL (challenge + state)
U->>B: open URL, enter credentials, solve captcha/MFA
B->>U: redirect to bosch.com/boschcam?code=...&state=...
U->>A: paste callback URL into Admin UI
A->>B: POST /token (code + PKCE verifier)
B-->>A: access_token + refresh_token
A->>A: AES-encrypt + persist (info.access_token / info.refresh_token / info.fcm_creds)
A->>B: GET /v11/video_inputs (with bearer)
B-->>A: camera list
A->>A: build per-camera DP tree, start FCM listener
Архитектура
flowchart LR
Cam["Bosch Cameras<br/>Gen1 + Gen2<br/>HTTPS :443"] -->|TLS tunnel| Proxy["Adapter TLS proxy<br/>127.0.0.1:<port>"]
Cloud[Bosch CBS API<br/>residential.cbs<br/>.boschsecurity.com] -->|"FCM push<br/>OAuth2 PKCE<br/>REST: events / video_inputs<br/>/ lighting / privacy"| Adapter
Adapter[ioBroker Adapter<br/>Node.js] --> DPs[(Encrypted DPs<br/>encryptedNative)]
Proxy --> Adapter
DPs --> VIS[VIS / VIS-2<br/>Dashboard]
DPs --> Blockly[Blockly / JS<br/>automations]
Proxy -.->|rtsp://...<br/>LAN-bind opt| Recorders[BlueIris / Frigate<br/>iobroker.cameras]
Adapter -->|file-store| Snapshots[snapshot.jpg<br/>last_event_image]
Сетевое подключение
Хост ioBroker должен иметь доступ к IP-адресу каждой камеры в локальной сети. Облако Bosch автоматически обнаруживает IP-адрес камеры, но потоковое видео/снимки/RCP-трафик поступает напрямую от хоста ioBroker к камере. Если брандмауэр, граница VLAN или гостевая сеть блокируют этот путь, потоковое видео MJPEG/RTSP в реальном времени и снимки по запросу переключаются на (более медленный) облачный канал.
Необходимые порты
| Направление | Протокол / Порт | Цель | Необходимый |
|---|---|---|---|
| IP-адрес камеры (хост ioBroker) | TCP/443 | Снимки экрана, REST API камеры, прямая трансляция RTSPS (все данные передаются через одно TLS-соединение). | Да |
хост ioBroker →*.boschsecurity.com | TCP/443 | OAuth, удаленный/облачный резервный поток, регистрация push-уведомлений FCM | Да |
хост ioBroker →fcm.googleapis.com /mtalk.google.com | TCP/5228 | Push-уведомления FCM (автоматически переключаются на опрос) | Необязательный |
| Внешний рекордер (BlueIris/Frigate/iobroker.cameras) → хост ioBroker | TCP/stream_port | Локальное RTSP-реле, предоставляемое адаптером. | Только при использовании |
Для работы адаптера требуется только протокол TCP/443 от хоста ioBroker к камере . Никакого UDP, никакой переадресации входящих портов на вашем маршрутизаторе.
Распространенные ошибки
- Камера находится в другой подсети/VLAN, чем ioBroker — например, камеры на
192.168.168.xи ioBroker на192.168.1.xМаршрутизатор/брандмауэр должен разрешать исходящий трафик с IP-адреса хоста ioBroker на IP-адрес камеры по протоколу TCP/443. - Изоляция гостевой сети IoT (FRITZ!Box "Gastzugang", гостевая сеть Unifi) по умолчанию блокирует соединение между локальными сетями.
- Камера доступна через приложение Bosch, но не через ioBroker — приложение взаимодействует через облако, поэтому это ничего не доказывает о доступности по локальной сети.
- Внешний регистратор не может связаться с ретранслятором — адаптер привязывает RTSP-ретранслятор к хосту ioBroker. Убедитесь, что ваша виртуальная машина/контейнер регистратора может связаться с ретранслятором.
stream_host:stream_portв локальной сети.
Быстрая проверка от хоста ioBroker.
nc -vz 192.168.x.y 443
curl -k -v --connect-timeout 5 https://192.168.x.y/ # alternative
Если оба процесса приводят к таймауту или возвращают ошибку «соединение отклонено», проблема заключается во взаимодействии между ioBroker и камерой (сетью/брандмауэром), а не в адаптере.
Техническое обслуживание RSS-лента
sequenceDiagram
participant Tick as Adapter tick (hourly)
participant RSS as Bosch Community RSS
participant MP as maintenance parser
participant DP as info.maintenance.*
Tick->>RSS: fetch Wartungsarbeiten + Statusmeldungen
RSS-->>MP: raw feed entries (+ HTML fallback)
MP-->>MP: parse title / time window / camera_relevant
MP-->>DP: state: active / scheduled / past / recent / idle
DP-->>DP: last_notification written on state transition
Note over Tick,DP: reactive re-fetch (5 min cooldown) on any 5xx
В случае отключения облачных сервисов может потребоваться резервное подключение к локальной сети.
sequenceDiagram
participant DP as cameras.<id>.privacy_enabled<br/>cameras.<id>.front_light_enabled
participant Adapter
participant Cloud as Bosch CBS API
participant RCP as Camera LAN RCP
participant Cam as Camera LAN :443
DP->>Adapter: handlePrivacyToggle / _applyLightingState
Adapter->>Cloud: PUT /v11/.../privacy or lighting
Cloud-->>Adapter: 5xx (cloud outage)
Adapter->>Adapter: lan_ip known + Gen2?
Adapter->>RCP: RCP write (0x0d00 / 0x0c22)
RCP->>Cam: HTTPS Digest + payload
Cam-->>Adapter: 200 OK (local fallback)
Adapter-->>DP: update + _localWriteAt stamp
Статус
Стабильная версия (v1.8.2) — проверена в реальном времени на 4 камерах (Gen1 + Gen2, FW 7.91.56 / 9.40.102) на реальном экземпляре ioBroker. Контракты Cloud API подтверждены для iOS-приложения через mitmproxy.
Что работает:
- Вход в систему OAuth2 PKCE через браузер с использованием Bosch SingleKey ID (без программной обработки паролей — капча/многофакторная аутентификация происходят в браузере).
- Автоматическое обновление токенов (примерно 45 минут в минуту; 4xx → требуется повторный вход в систему, 5xx → бесшумная повторная попытка). Сохранено
refresh_tokenтакже используется при запуске для создания свежегоaccess_tokenРаботает бесшумно — после перезапуска не требуется повторный вход в систему PKCE, даже если адаптер был остановлен дольше, чем истекает срок действия токена доступа (1 час). - Обнаружение камер (Gen1 + Gen2,
GET /v11/video_inputs) - Дерево состояний для каждой камеры:
name,firmware_version,hardware_version,generation,online,privacy_enabled,light_enabled,front_light_enabled,wallwasher_enabled,image_rotation_180,snapshot_trigger,motion_trigger,motion_trigger_event_type,snapshot_path,stream_url,stream_host,stream_port,stream_path,last_motion_at,last_motion_event_type— а также ежедневные счетчики событий, чтение и запись данных о зонах движения/масках конфиденциальности/правилах, статус прошивки и установка, а также данные о совместном использовании файлов cookie друзьями второго поколения (версии 1.2.0–1.8.0, полный список в разделе «Данные» ниже) - Переключение режима конфиденциальности через API Bosch Cloud
PUT /v11/video_inputs/{id}/privacy - Переключатель освещения, специфичный для поколения и теперь разделенный на независимые точки данных:
- Поколение 2:
PUT /lighting/switch/front+/topdown - Поколение 1:
PUT /lighting_override(передний свет включен + подсветка стены включена) front_light_enabledиwallwasher_enabledможно переключать независимо;light_enabledостается устаревшим комбинированным коммутатором
- Поколение 2:
- Синтетический триггер движения (
motion_triggerкнопка только для записи +motion_trigger_event_typeселектор) для интеграции внешнего датчика без ожидания отправки команды Bosch FCM - Триггер моментального снимка записывает изображение JPEG в файловое хранилище адаптера.
/<namespace>/cameras/<id>/snapshot.jpg), с автоматической повторной попыткой при первом сообщении об ошибке «поток прерван», которое выдает прошивка Bosch Gen2 после простоя. Один снимок при запуске для каждой камеры.cameras.<id>.onlineпо умолчаниюfalseнемедленно в реальное состояние. - TLS-прокси для каждой камеры:
stream_url = rtsp://127.0.0.1:<port>/rtsp_tunnelдля использования вiobroker.camerasили go2rtc. По своей сути, это только локальная связь — облачная ретрансляция недоступна. - RTSP-сервер для мониторинга сессий: локальные сессии автоматически обновляются примерно за 60 секунд до истечения срока действия.
maxSessionDurationСрок действия истекает — круглосуточная запись работает без ежечасных обрывов трансляции. - Слушатель push-уведомлений FCM (
@aracna/fcm@1.0.32MTalk/MCS) для событий, происходящих с движением/звуковой сигнализацией/появлением человека, с интервалом менее секунды.info.fcm_activeотражает состояние:healthy/polling/error/disconnected/stoppedЕсли регистрация push-уведомлений не удаётся, адаптер переключается на другой способ./v11/eventsопрос каждые 60 секунд (info.fcm_active=pollingСобытия по-прежнему поступают, но с большей задержкой. Интервал опроса можно настроить черезpoll_intervalНастройки (запросы API / вкладка «Энергосбережение», версия 1.4.1 и выше). - Зашифрованное хранилище учетных данных (
encryptedNative— js-контроллер шифрует токен обновления в состоянии покоя) - Уровень управления Cloud-API WRITE (v1.8.0): зоны обнаружения движения, маски конфиденциальности, правила автоматизации (создание/обновление/удаление), совместное использование камер Gen2 (поделиться/пригласить/удалить друга) и триггер установки прошивки — то же самое.
/v11В качестве конечных точек используются интеграция с Home Assistant и интерфейс командной строки Python, байтовая проверка которых выполнена в обоих случаях. Редактор зон/масок RCP на устройстве остается в режиме ожидания до предоставления Bosch более широкого доступа к локальной записи. - В версии 1.8.1 используются объединенные HTTPS-соединения с возможностью поддержания соединения для локальных запросов Digest и облачных API, вместо нового рукопожатия TCP+TLS для каждого вызова.
- Пройдено более 1480 модульных тестов
Точки данных
Данные по каждой камере в пределахcameras.<id>.* :
| Точка данных | Тип | Описание |
|---|---|---|
name | нить | Название камеры (из учетной записи Bosch) |
firmware_version | нить | Текущая версия прошивки |
hardware_version | нить | Строка модели оборудования |
generation | нить | Gen1 или Gen2 |
online | логический | Камера доступна |
privacy_enabled | логический | Включение/выключение режима конфиденциальности |
front_light_enabled | логический | Передний прожектор включен/выключен |
wallwasher_enabled | логический | Включение/выключение RGB-подсветки стен (для наружного применения, второе поколение) |
wallwasher_color | нить | ШЕСТНАДЦАТЬ#RRGGBB , пустой = режим теплого белого |
wallwasher_brightness | число | 0–100 |
top_led_brightness | число | 0–100, Gen2 для наружного освещения — только верхняя группа светодиодов (независимо отwallwasher_brightness ) |
bottom_led_brightness | число | 0–100, Gen2 для наружного освещения — только нижняя группа светодиодов (независимо отwallwasher_brightness ) |
front_light_white_balance | число | -1.0 (холодный/6500K) .. 1.0 (теплый/2000K), уличный фронтальный прожектор Gen2 — соответствует полярности интеграции с Home Assistant. |
soft_light_fading | логический | Плавное включение/выключение светодиода при достижении порога темноты (для наружного применения Gen2) |
rename | нить | Напишите новое название для камеры — PUT /v11/video_inputs |
soft_reset | кнопка | Перезагрузите камеру |
hard_reset_confirm | нить | Введите точное текущее название камеры, затем напишитеhard_reset=true в течение 60 секунд — защитный механизм, истекает и должен быть набран заново через 60 секунд или после любой отклоненной попытки. |
hard_reset | кнопка | Деструктивное действие : сброс настроек камеры до заводских (требуется)hard_reset_confirm (для первого совпадения) — камера теряет связь с учетной записью Bosch и должна быть повторно введена в эксплуатацию. |
ai_description | нить | Анализ с помощью ИИ: описание последнего проанализированного снимка (см. Анализ камеры с помощью ИИ ) |
ai_score | число | Анализ с помощью ИИ: оценка степени подозрения 1 (доброкачественный) – 10 (высокая степень подозрения) |
ai_last_analysis | число | Анализ с использованием ИИ: временная метка epoch-ms последнего завершенного анализа. |
ai_analyze | кнопка | Запустить анализ ИИ на основе последнего снимка состояния системы. |
image_rotation_180 | логический | Переворот изображения на 180° |
livestream_enabled | логический | Включение/отключение прямой трансляции RTSP |
stream_url | нить | rtsp://user:pwd@host:port/rtsp_tunnel?inst=1&… |
stream_url_sub | нить | URL подпотока (inst=2 экспериментальный) |
stream_host | нить | Хостинг-частьstream_url — вставьте в iobroker.cameras "Camera IP" |
stream_port | число | Портовая частьstream_url — вставьте в iobroker.cameras "Port" |
stream_path | нить | Путь+запросstream_url — вставьте в iobroker.cameras "Путь" (Протокол = TCP) |
snapshot_trigger | кнопка | Загрузите новый JPEG-файл в snapshot_path |
snapshot_path | нить | Путь к хранилищу файлов для последнего JPEG-файла |
last_event_image | нить | Base64data:image/jpeg;base64,… (Автоматический снимок при движении) |
last_event_image_at | нить | Отметка времени ISO 8601 последнего изображения события |
motion_trigger | логический | Писатьtrue внедрить синтетическое событие движения |
motion_trigger_event_type | нить | motion/person / audio_alarm |
motion_active | логический | Триггер по фронту сигнала:true в течение 90 секунд после начала движения, затем false |
last_motion_at | нить | Временная метка ISO 8601 последнего события движения |
last_motion_event_type | нить | motion /person / audio_alarm |
pan_position | число | Угол поворота ±120° (360° только для первого поколения) |
pan_preset | нить | Названный пресет:home ,left ,right ,back-left , back-right |
siren_active | логический | Сирена Trigger 75 дБ (Gen2 Indoor II) |
lan_reachable | логический | Результат TCP-пинга по IP-адресу локальной сети камеры |
lan_ip | нить | IP-адрес камеры в локальной сети (сохраняется при каждом открытии сессии) |
maintenance_state | нить | active /scheduled / none |
intrusion_sensitivity | число | Чувствительность DualRadar 1–5 (Gen2) |
intrusion_distance | число | Дальность обнаружения DualRadar: 1–8 м (Gen2) |
wifi_signal_pct | число | Уровень сигнала Wi-Fi 0–100 % |
mic_level | число | Уровень записи микрофона 0–100 |
speaker_level | число | Громкость динамика внутренней связи 0–100 |
last_status_notification | нить | JSON: полезная нагрузка для перехода камеры в онлайн/оффлайн режим. |
_proxy_port | число | Порт TLS-прокси (сохраняется после перезапусков) |
events_today | число | Общее количество событий в облаке за сегодня (по UTC) |
movement_count | число | События, связанные с движением транспорта, сегодня (по UTC). |
audio_count | число | Сегодня (по UTC) зафиксированы звуковые тревожные события. |
motion_enabled | логический | Включение/выключение обнаружения движения |
motion_sensitivity | нить | Выбор чувствительности к движению |
detection_mode | нить | Поколение 2:all_motions /only_humans / zones |
record_sound | логический | Запись звука вместе с видео |
notifications_enabled | логический | Главный переключатель push-уведомлений |
notify_movement /notify_person /notify_audio /notify_trouble /notify_camera_alarm /notify_trouble_email | логический | Переключатель push-уведомлений для каждого типа событий |
motion_zones | строка (JSON) | Зоны, чувствительные к движению, необработанные данные{x,y,w,h} массив (зеркало только для чтения) |
motion_zones_count | число | Количество настроенных зон движения |
motion_zones_set | строка (JSON, запись) | v1.8.0 — запись JSON-массива{x,y,w,h} (0,0–1,0) для замены всех зон;[] очищает их |
privacy_masks | строка (JSON) | Маски для обеспечения конфиденциальности, необработанные{x,y,w,h} массив (зеркало только для чтения) |
privacy_masks_count | число | Количество настроенных масок конфиденциальности |
privacy_masks_set | строка (JSON, запись) | v1.8.0 — запись JSON-массива{x,y,w,h} (0,0–1,0) для замены всех масок;[] очищает их |
rules | строка (JSON) | Правила автоматизации, необработанный массив {id,name,isActive,startTime,endTime,weekdays} |
rules_count | число | Количество настроенных правил автоматизации |
rule_create | строка (JSON, запись) | v1.8.0 — запись{name,isActive,startTime:"HH:MM:SS",endTime:"HH:MM:SS",weekdays:[0-6]} создать правило |
rule_update | строка (JSON, запись) | v1.8.0 — запись{id,...changed fields} (GET-merge-PUT) |
rule_delete | строка (запись) | v1.8.0 — записать идентификатор правила для удаления |
lighting_schedule_status | нить | Только для первого поколения — прожекторscheduleStatus режим |
lighting_schedule | строка (JSON) | Только для первого поколения — в необработанном видеlighting_options расписание |
ambient_light_schedule | строка (JSON) | График работы наружного освещения Gen2 (/lighting/ambient ) |
ambient_light_enabled | логический | Уличное освещение Gen2 — подсветка, управляемая окружающим светом |
motion_light_enabled /motion_light_sensitivity | логическое значение / число | Уличный светильник Gen2 с датчиком движения |
darkness_threshold | число | Порог темноты при окружающем освещении |
shared_with_friends | строка (JSON) | Только для Gen2 — эта камера используется совместно с друзьями (массив без данных) |
shared_with_friends_count | число | Только для второго поколения — количество вышеуказанных |
camera_share | строка (JSON, запись) | v1.8.0 , только для Gen2 — запись{"friendId":"...","days":30} (days (необязательно = неопределенно) поделиться этой камерой |
friend_invite | строка (запись) | v1.8.0 , только для Gen2 — пригласите друга по электронной почте (приглашение действует для всей учетной записи, а не только для конкретной камеры). |
friend_remove | строка (запись) | v1.8.0 , только для Gen2 — удаление друга по ID (для всей учетной записи) |
firmware_current_version | нить | Установленная версия прошивки камеры (по данным из облака) |
firmware_latest_version | нить | Последняя доступная версия прошивки камеры (полученная из облачного хранилища) |
firmware_update_available | логический | Доступно обновление прошивки |
firmware_updating | логический | В данный момент выполняется установка прошивки. |
firmware_install | кнопка | v1.8.0 — записьtrue установить ожидающее обновление прошивки (защищено от двойного нажатия или уже выполняющейся установки) |
commissioned | логический | GET /commissioned — Камера настроена, подключена и введена в эксплуатацию |
unread_events_count | число | Непрочитанные облачные события (изGET /v11/events ) |
mark_all_read | кнопка | Помечает все облачные события как прочитанные. |
autofollow_enabled | логический | Только для 360° Gen1 — автоматическое следование за движением |
alarm_arm /alarm_mode /pre_alarm | логический | Управление системой сигнализации Gen2 Indoor II |
alarm_state | нить | Состояние системы сигнализации Gen2 Indoor II |
pre_alarm_delay /alarm_activation_delay | число | Время срабатывания сигнализации Gen2 Indoor II |
siren_duration | число | длительность срабатывания тревожной сирены |
glass_break_detection /fire_alarm_detection | логический | Gen2 Audio+ — обнаружение звука разбития стекла / дыма / пожара |
privacy_sound_enabled | логический | Звуковой сигнал режима конфиденциальности |
status_led | логический | Gen2 — светодиодный индикатор состояния (вкл/выкл) |
timestamp_overlay | логический | Наложение временной метки на экран |
power_led_brightness | число | Светодиоды Gen2 для использования в помещении — высокая яркость светодиодов |
front_light_intensity | число | Яркость фронтальной фары |
intercom_enabled | логический | Gen2 — двусторонняя аудиосвязь |
microphone_level | число | Уровень записи микрофона 0–100 (илиmic_level ) |
onvif_scopes | строка (JSON) | Диагностика осциллографов ONVIF (данные из облака) |
rcp_version | нить | диагностика версии протокола RCP |
stream_quality | нить | Выбор качества потокового воспроизведения (высокое/низкое) |
snapshot_url | нить | Локальный URL HTTP-сервера для создания снимков (snapshot_http_port (см. Развитие ) |
session_limit_hit | логический | Для этой камеры была исчерпана квота на 3 сеанса съемки Bosch. |
wifi_ssid | нить | SSID Wi-Fi камеры |
lens_elevation | число | Gen2 Outdoor II — параметр высоты установки |
Данные, доступные в масштабе всего адаптера, находятся в разделеinfo.* :
| Точка данных | Описание |
|---|---|
connection | Логическое значение — подключена как минимум одна камера. |
connection_status | logged_out /awaiting_login /connected / auth_error |
login_url | URL-адрес Bosch OAuth (активная ссылка в административном интерфейсе) |
last_login_at | ISO 8601 последнего успешно выпущенного токена |
fcm_active | healthy /polling /error /disconnected / stopped |
maintenance.state | active /scheduled /past /recent /unknown / idle |
maintenance.title | Разобранный заголовок объявления |
maintenance.scheduled_start | Начало стандарта ISO 8601 |
maintenance.scheduled_end | ISO 8601 конец |
maintenance.camera_relevant | Логическое значение — в объявлении упоминаются камеры |
maintenance.last_fetched | ISO 8601 последнего успешного запроса RSS |
maintenance.last_notification | JSON-данные для маршрутизации уведомлений Blockly |
Панель управления
Пример панели мониторинга VIS-2, готовый к импорту, находится вdocs/vis-2-example/ — Все четыре камеры расположены в сетке 2×2 с обновлением снимков (каждые 5 секунд), переключателями конфиденциальности и освещения, кнопкой запуска снимка и строкой состояния.
Быстрая установка:
cp docs/vis-2-example/vis-views.json ~/iobroker-data/files/vis-2.0/main/
iobroker restart vis-2
Затем откройтеhttp://HOST:8082/vis-2/index.html#Cameras в вашем браузере.
Видетьdocs/vis-2-example/README.md В пошаговом руководстве описано, как поменять местами UUID камер и как подключить go2rtc / HLS для передачи видео в реальном времени с низкой задержкой вместо стандартного обновления снимков.
Виджет камеры VIS-2
Адаптер поставляется с двумя встроенными виджетами VIS-2 (React / Module-Federation, созданными на основеsrc-widgets/ ), который можно перетащить в любое представление VIS-2 без импорта JSON-файла.
Требования: установлен и запущен адаптер VIS-2 версии ≥ 2.13.
Фотоаппарат Bosch (однокамерный)
Способ применения:
- Откройте редактор VIS-2 (
http://HOST:8082/vis-2/index.html?edit=1). - На панели виджетов найдите набор виджетов «Умная домашняя камера Bosch» .
- Перетащите камеру Bosch на поле зрения.
- Установите точку данных камеры на любую точку данных в разделе
bosch-smart-home-camera.0.cameras.<UUID>(например.name) — камера автоматически определяется по траектории движения. - Выберите режим потоковой передачи (см. ниже).
Режимы потоковой передачи:
| Режим | Что это показывает | Потребности | Аудио |
|---|---|---|---|
| Снимок (почти в режиме реального времени) (по умолчанию) | <img> получено с HTTP-сервера, отображающего моментальные снимки адаптера (snapshot_url ) с настраиваемым интервалом (по умолчанию 1 с) | snapshot_http_port установлен в адаптере | нет |
| MJPEG (кадры) | Непрерывная передача кадров JPEG из локального RTSP-прокси через FFmpeg, отображаемых на холсте; кнопка воспроизведения запускает поток. | livestream_enabled = true +ffmpeg на хосте | нет |
| go2rtc WebRTC | Низкозадержечная потоковая передача видео через нативный интерфейс<video> элемент + WebRTC; автоматическое переключение на HLS в случае сбоя ICE. | go2rtc запущен с использованием камерstream_url в качестве источника | да — переключение звука + ползунок громкости + защита от паузы |
Набор функций:
- Значки статуса: Онлайн/Офлайн, Движение, Конфиденциальность, Подключение (мигающее), Время работы потока, Баннер резервного режима HLS, Последнее событие, Баннер технического обслуживания
- Состояние конфиденциальности и офлайн-режим четко разделены; онлайн-статус согласован с облачными сервисами.
- Ограничение на воспроизведение одним касанием (без автоматического запуска); защита от задержки трансляции и обеспечения конфиденциальности.
- Оптимистичный пользовательский интерфейс: кнопки-переключатели мгновенно переключаются, автоматически возвращаются в исходное состояние при ошибке.
- Цифровое масштабирование (щипок/колесико) в полноэкранном режиме.
- API видимости страниц: скорость создания снимков ограничивается в фоновом режиме.
- SVG-наложения для зон движения и масок конфиденциальности
- Кнопки панорамирования ◀◀ ◀ ▶ ▶▶ с отображением положения; только для внутреннего устройства Gen1 360° (
hardware_version==="INDOOR") - Панель управления с матовым стеклом (тема iOS/Android/Auto; обычный/минимальный/компактный макет)
- Полноэкранный режим через портал React (закрывает весь экран)
- Режим «картинка в картинке» (режим WebRTC): прямая трансляция вставляется в плавающее окно браузера, которое всегда находится поверх всех приложений в Safari на macOS и поверх самого браузера в Chrome. В заголовке окна отображается название камеры. Браузер разрешает только одно окно «картинка в картинке», поэтому, пока одна камера плавает, кнопка «картинка в картинке» на каждом втором виджете BoschCamera в окне становится неактивной; она сохраняется после повторного подключения к потоку. Скрыто там, где в браузере отсутствует режим «картинка в картинке» (большинство WebView на iOS/Android, режимы снимков/MJPEG).
- Складные нижние панели-гармошки для всех расширенных настроек: уведомления, расширенные настройки, автоматизация/безопасность Gen2, освещение и камера (включая...).
front_light_intensityползунок), диагностика, зоны, услуги - 11 языков пользовательского интерфейса (de/en/es/fr/it/nl/pl/pt/ru/uk/zh-cn)
Субтитры и перевод в реальном времени (функция браузера, без настройки): если ваша камера имеет аудиовход, Chrome → Настройки → Специальные возможности → Субтитры в реальном времени расшифровывает речь в потоке WebRTC на устройстве в режиме реального времени, а функция Live Translate может перевести субтитры на ваш язык. Изменения виджетов не требуются — субтитры отображаются независимо от того, какой звук воспроизводится во вкладке (работает совместно с режимом «Картинка в картинке»).
Создание виджета (для участников):npm run build:widget устанавливаетsrc-widgets/ запускает сборку Vite/Module-Federation и копирует пакет вwidgets/bosch-smart-home-camera/ .
Обзор камер Bosch (многокамерная сетка)
Виджет «Обзор камер Bosch» отображает все камеры адаптера в адаптивной сетке — без необходимости ручной настройки каждой камеры.
Поля конфигурации:
| Поле | Описание |
|---|---|
| Экземпляр адаптера | напримерbosch-smart-home-camera.0 |
| Колонки | Фиксированное количество столбцов (0 = автоматическое) |
| Минимальная ширина плитки | Минимальная ширина на плитку в пикселях |
| Скрыть статус "офлайн" | Не показывайте камеры, не подключенные к сети. |
| Элементы управления для отдельных плиток | Переключатели конфиденциальности и освещения расположены непосредственно на каждой плитке. |
Набор функций:
- Автоматическое обнаружение всех камер выбранного экземпляра
- Сортировка: сначала онлайн, затем конфиденциальность, затем офлайн.
- Функция «Развернуть по клику»: щелчок по плитке открывает камеру в виде виджета BoschCamera в полноэкранном режиме.
- Аналогичные индикаторы состояния, как у BoschCamera (Онлайн/Офлайн/Движение/Конфиденциальность).
Примеры автоматизации
В библиотеке постоянно пополняются 20 готовых к импорту скриптов.docs/examples/ — 8 XML-файлов Blockly для визуального редактора и 12 простых фрагментов кода JavaScript, расположенных рядом. Охваченные темы:
- Главные переключатели — одна виртуальная точка данных синхронно переключает режимы работы (подсветка стен/конфиденциальность) на каждой камере.
- Обработка движения — снимок при движении с уведомлением, мост движения Hue-PIR → синтетический датчик движения Bosch, уведомление о пакетной агрегации, конфиденциальность на основе присутствия.
- Сценарии освещения — автоматическая мойка стен с управлением в сумерках, сцена освещения подъездной дорожки (прожектор Hue + мойка стен/подсветка Bosch), средство отпугивания во время отпуска, подсветка с датчиком открытия двери.
- Интеграция бота/панели управления — Telegram
/snapкоманда, слайд-шоу последнего события для VIS, передача URL-адреса потока на планшет Fully Kiosk. - Статус и безопасность — оповещение об отключении камеры, мониторинг износа FCM-push, срабатывание аварийной сирены, подавление оповещений в зависимости от погодных условий, отключение звука в спящем режиме, координация с гаражными воротами, расписание ночного режима.
- Планировщик моментальных снимков / замедленная съемка —
docs/examples/snapshot-blockly.md: ежечасный планировщик Blockly XML + JavaScript (cron с 06:00 до 22:00), а также вариант, срабатывающий при обнаружении движения, с ограничением по времени в 15 минут. Записьsnapshot_trigger, перечитывает в ответsnapshot_pathВключает в себя однострочный скрипт ffmpeg для сборки собранных JPEG-файлов в таймлапс в формате mp4.
Откройте JavaScript-адаптер → Скрипты → Создать новый Blockly (или JavaScript) → Вставьте. Замените<CAM_UUID> /<PRESENCE_OID> В папке /lux-sensor/Telegram-bot находятся заполнители с вашими фактическими идентификаторами объектов из вкладки «Объекты». В файле README этой папки содержится полный индекс, необходимые компоненты и шаблоны вызовов адаптеров уведомлений (Telegram, signal-cmb, Pushover, email).
→ Внесите свой вклад : разместите рабочий скрипт в виде блока кода в теме форума ioBroker или создайте запрос на слияние (PR) — примеры от сообщества приветствуются.
Последовательность событий/движений (камера → оператор → автоматизация)
flowchart TD
Cam[Camera detects motion<br/>or audio alarm] -->|FCM push<br/>MTalk/MCS| L[Adapter FCM listener<br/>_aracna/fcm_]
L -->|persistent_id dedup| F{fetchEvents<br/>GET /v11/events}
F -->|new event| N["normalize event:<br/>id, type, tags, timestamp"]
N --> C{eventTags / type}
C -->|MOVEMENT + PERSON| EP[last_event_type=person<br/>motion_active=true 90s]
C -->|MOVEMENT| EM[last_event_type=movement<br/>motion_active=true 90s]
C -->|AUDIO_ALARM| EA[last_event_type=audio_alarm]
EP & EM & EA --> S[fetch snapshot<br/>→ snapshot.jpg<br/>→ last_event_image base64]
EP & EM & EA --> T[Blockly / JS trigger]
T -->|sendTo notify| Out[Telegram / Signal /<br/>Pushover / e-mail]
L -.->|register fail<br/>3x| Poll[Polling fallback<br/>every 30s<br/>info.fcm_active=polling]
Примечание по поводу потоковой передачи в браузере : ни один браузер не поддерживает RTSP изначально. Адаптер публикует данные для каждой камеры.stream_url (rtsp://<user>:<password>@127.0.0.1:<port>/rtsp_tunnel?… ) через локальный TLS-прокси для использования с ffmpeg / mpv /iobroker.cameras / go2rtc. Для самого VIS используйте либо обновление снимков, как в примере панели мониторинга, либо мост через go2rtc → WebRTC/HLS.
stream_url пусто / go2rtc выдает сообщение "соединение отклонено"
Прямая трансляция по умолчанию отключена и активна по желанию — каждая открытая сессия учитывается в квоте локальных сессий Bosch и поддерживает работу TLS-прокси и сторожевого таймера круглосуточно, поэтому адаптер никогда не запускает их самостоятельно. В отключенном состоянии прокси для каждой камеры не прослушивает запросы.cameras.<id>.stream_url остается пустым, и любой go2rtc/рекордер, направленный на этот порт, получаетconnection refused Снимки экрана и события движения работают и без него.
- Набор
cameras.<id>.livestream_enabled = true(для каждой камеры). Сессия открывается, прокси-сервер начинает прослушивание, иcameras.<id>.stream_urlзаселен. - Скопируйте этот URL-адрес в go2rtc /
iobroker.cameras/ ваш диктофон. - Если go2rtc (или программа записи) работает на другом хосте , отличном от ioBroker, то используется значение по умолчанию.
127.0.0.1Связать оттуда невозможно → всё ещёconnection refusedВключите параметр «Предоставить доступ к RTSP-прокси в локальной сети» в настройках адаптера и укажите внешнее имя хоста / IP-адрес локальной сети (см. шаги по настройке LAN-рекордера ниже); в этом случае URL-адрес будет использовать IP-адрес вашей локальной сети хоста ioBroker вместо внешнего имени хоста.127.0.0.1.
Мост MQTT
При включении адаптер публикует каждое событие движения/человека/аудиосигнализации в виде сообщения JSON в выбранный вами MQTT-брокер, делая события с камер Bosch доступными для любого потребителя MQTT без необходимости использования привязок, специфичных для ioBroker.
Административный интерфейс → вкладка "MQTT Bridge":
| Поле | По умолчанию | Описание |
|---|---|---|
| Включить мост MQTT | false | Главный выключатель |
| Хост брокера / IP-адрес | — | Имя хоста или IP-адрес, например192.168.1.10 |
| Порт брокера | 1883 | 1–65535 |
| Используйте TLS (mqtts://) | false | Зашифрованное соединение |
| Имя пользователя | — | Необязательный |
| Пароль | — | Необязательно, хранится в зашифрованном виде. |
| Префикс темы | bosch/cameras | Все темы находятся под этим префиксом. |
Структура темы:
<prefix>/<cam-uuid>/motion motion or unclassified movement
<prefix>/<cam-uuid>/person person detected
<prefix>/<cam-uuid>/audio audio_alarm event
Полезная нагрузка (JSON):
{
"timestamp": "2026-05-20T10:00:00.000Z",
"cam_name": "Front Door",
"event_id": "evt-uuid-or-empty",
"event_type": "motion"
}
Совместимые потребители: Node-RED, openHAB, Home Assistant (интеграция с MQTT), Frigate, Zigbee2MQTT sidecar-контейнеры, любой стандартный подписчик MQTT.
Пример подписки Node-RED:
bosch/cameras/<camera-id>/motion
Подключите его к системе уведомлений Telegram, системе оповещений Frigate или Home Assistant.mqtt.sensor — На стороне абонента адаптер ioBroker не требуется.
Анализ камер с помощью ИИ
Необязательный параметр, отключен по умолчанию. В отличие от интеграции с Home Assistant (которая делегирует обработку данных отдельно настраиваемому компоненту).ai_task Интеграция), ioBroker не имеет эквивалентной абстракции поставщика задач — эта функция вместо этого отправляет POST-запрос на последнюю точку доступа HTTPS, которую вы настраиваете , и ожидает в ответ небольшой JSON-ответ. Это мост для API обработки изображений, а не встроенный клиент ИИ.
Административный интерфейс → вкладка «Анализ с помощью ИИ»:
| Поле | По умолчанию | Описание |
|---|---|---|
| Включить анализ камер с помощью ИИ | false | Главный выключатель |
| URL конечной точки | — | HTTPS-конечная точка, принимающая POST-запрос, указанный ниже. |
| ключ API | — | Необязательно, отправляется какAuthorization: Bearer <key> хранится в зашифрованном виде |
Запрос (POST <endpoint> ):
{
"camera": "Terrasse",
"image_base64": "<JPEG bytes, base64>"
}
Ожидаемый ответ:
{
"description": "Person walking near the door.",
"score": 7
}
score оценивается по шкале от 1 (доброкачественное) до 10 (вызывает серьезные подозрения).
Использование: записьtrue кcameras.<id>.ai_analyze (например, из системы автоматизации движения или вручную). Адаптер получает новый снимок состояния, отправляет его методом POST и записывает ответ в...cameras.<id>.ai_description /ai_score /ai_last_analysis Сохраняется только последний результат — этот фрагмент не включает в себя постоянно сохраняемый журнал истории оповещений (интеграция HA).ai_alert_store.py Есть один; может быть добавлен позже, если будет спрос).
Бесконтактный RTSP-вход
Камеры Bosch используют только протокол RTSPS (RTSP, туннелированный внутри TLS) с частным сертификатом центра сертификации Bosch, который большинство программ для видеорегистраторов (BlueIris, Frigate, VLC, go2rtc) не могут обрабатывать напрямую, и для каждого потока требуется подтверждение подлинности Bosch Digest с учетными данными, которые Bosch обновляет при каждом продлении сессии и каждом переключении режима конфиденциальности . Этот адаптер является оригинальной реализацией локального RTSP-ретранслятора, решающего обе проблемы — позже он был выпущен как RTSP-конечная точка без учетных данных в сопутствующей интеграции с Home Assistant (v14.1.0), в которой этот адаптер явно указан как исходный код.
Реле имеет три уровня, все только для локального доступа (этот адаптер никогда не использует облачное медиа-реле Bosch — нет).proxy-NN.live.cbs.boschsecurity.com (прямо на IP-адрес камеры в локальной сети по протоколу TCP/443):
- Локальная сессия Bosch (
src/lib/live_session.ts) —PUT /v11/video_inputs/{id}/connection {type:"LOCAL"}Открывает сессию и возвращает LAN-адрес камеры плюс дайджест.user/passwordпара, действительна доmaxSessionDuration(по умолчанию 3600 с) или раннее вращение. - TLS-прокси (
src/lib/tls_proxy.ts) — обычный TCP-слушатель (net.createServer) который открываетtls.connect()к локальному адресу камеры для каждого входящего клиента и передает байты дальше, обеспечивая чистый вывод.rtsp://Конечная точка для потребителя. Автоматический выключатель замыкает соединение после 5 последовательных сбоев подключения в течение 30 секунд, чтобы действительно недоступная камера не вращалась бесконечно. - Прозрачная инъекция гидролизата (
src/lib/rtsp_auth.ts) — небольшой конечный автомат RTSP, расположенный перед каналом TLS. Клиент, который уже отправляет свои собственные данные.Authorization:Заголовок (для устаревших клиентов, использующих учетные данные в URL) передается напрямую. Для всего остального выполняется рукопожатие Digest: прокси-сервер перехватывает данные с камеры.401 + WWW-Authenticateвычисляет ответ и вставляет новый фрагмент.Authorization: Digest …В заголовок каждого последующего запроса клиента добавляется имя пользователя или пароль — регистратор никогда не видит ни имени пользователя, ни пароля. Когда Bosch меняет учетные данные дайджеста сессии (переключение конфиденциальности, обновление),updateDigestAuth()позволяет быстро заменять их для будущих подключений без перезапуска слушателя или изменения опубликованного URL-адреса.
sequenceDiagram
autonumber
participant Rec as Recorder<br/>(BlueIris / Frigate / go2rtc / VLC)
participant FD as Lazy front-door<br/>always-listening, sticky port
participant Proxy as Inner TLS proxy<br/>(tls_proxy.ts)
participant Auth as Digest injector<br/>(rtsp_auth.ts)
participant Bosch as Bosch Cloud API
participant Cam as Camera LAN :443<br/>(RTSPS)
Rec->>FD: TCP connect rtsp://host:<port>/rtsp_tunnel
Note over FD: port is always bound —<br/>no "Connection refused" even if idle
FD->>FD: resolveInner() — any live client already?
alt no active Bosch session
FD->>Bosch: PUT /connection {type:"LOCAL"}
Bosch-->>FD: lanAddress + digestUser/digestPassword
FD->>Proxy: startTlsProxy(remote=lanAddress, digestAuth)
end
FD->>Proxy: pipe client -> 127.0.0.1:<innerPort>
Proxy->>Cam: tls.connect()
Cam-->>Proxy: 401 + WWW-Authenticate: Digest
Proxy->>Auth: compute Digest response
Auth->>Cam: retry with Authorization: Digest ... (no creds from Rec)
Cam-->>Rec: RTSP 200 OK, media flows
Note over Bosch,Cam: privacy toggle / renewal rotates creds
Bosch-->>FD: fresh digestUser/digestPassword (heartbeat/renew)
FD->>Proxy: updateDigestAuth(user, password)
Note over Proxy: future connections use rotated creds,<br/>in-flight streams untouched
Rec-->>FD: last client disconnects
FD->>FD: idle linger (stream_persistent_idle_timeout, default 60s)
FD->>Bosch: DELETE /connection (release Bosch session slot)
Note over FD: front-door itself stays bound —<br/>next connect re-opens on demand
Два режима работы, оба обозначены одинаково.stream_url точка данных:
| Режим | Конфигурация | Поведение порта |
|---|---|---|
| По запросу (по умолчанию) | cameras.<id>.livestream_enabled = true | TLS-прокси прослушивает поток только тогда, когда он явно включен; по умолчанию он выключен, поэтому он никогда не занимает общий слот сессии Bosch без приглашения. |
| Постоянно включенная входная дверь | stream_persistent_endpoint = true (Вкладка RTSP / Поток) | Отдельный ленивый слушатель (src/lib/lazy_stream.ts ) остается привязанным к "липкому" порту навсегда; он открывает сессию Bosch + внутренний прокси при первом подключении клиента и снова освобождает сессию Bosch после этого.stream_persistent_idle_timeout (10–3600 с, по умолчанию 60 с) режим ожидания — рекомендуется для регистраторов, которые опрашивают систему по собственному расписанию (форум #84538) |
Интерфейс настроек (Административный интерфейс → вкладка "RTSP / Потоковая передача"):
| Поле | Собственный ключ | По умолчанию | Цель |
|---|---|---|---|
| Предоставить доступ к RTSP-прокси для локальной сети. | rtsp_expose_to_lan | false | Связывать0.0.0.0 вместо127.0.0.1 таким образом, регистратор на другом хосте сможет получить к нему доступ. |
| Внешнее имя хоста / IP-адрес локальной сети | rtsp_external_host | "" | Хост встроен в опубликованныйstream_url при воздействии локальной сети |
| Максимальная продолжительность сессии (с) | stream_max_session_duration | 0 (Настройки камеры по умолчанию, 3600 с) | Поднимите уровень, чтобы поддерживать непрерывный поток энергии дольше между обновлениями (600–21600 с). |
| Обеспечьте постоянную доступность конечной точки RTSP. | stream_persistent_endpoint | false | Включает в себя описанную выше функцию постоянно включенной «ленивой» входной двери. |
| Освободить сессию после простоя (с) | stream_persistent_idle_timeout | 60 | Окно ожидания перед запуском сеанса Bosch по запросу за передней дверью (10–3600 с) |
Примечание по безопасности: управление доступом осуществляется только через переключатель хоста привязки (127.0.0.1 против.0.0.0.0 /LAN-IP) — на самом RTSP-сервере нет списка разрешенных IP-адресов или дополнительного уровня аутентификации/базовой аутентификации, поэтому относитесь к «Открытию RTSP-прокси для локальной сети» так же, как и к любой другой неаутентифицированной службе локальной сети, и держите его отключенным за пределами доверенной сети. Скрытые учетные данные Digest принадлежат Bosch, а не являются заменой механизма контроля доступа для вашей собственной сети.
Схема портов: один порт TLS-прокси на каждую камеру (и, при включенной постоянной конечной точке, тот же самый «липкий» порт также используется в качестве порта на входной двери); выбирается свободным при первом использовании и сохраняется после перезапусков и обновления сессий Bosch.cameras.<id>._proxy_port Таким образом, сохраненный URL-адрес записывающего устройства продолжает работать неограниченно долго без перенастройки.
Внешние регистраторы (BlueIris, Frigate)
flowchart LR
Cam["Bosch Camera<br/>LAN :443<br/>HTTPS only"] -->|RTSP-over-TLS<br/>tunneled| Proxy["Adapter TLS proxy<br/>port: per-camera<br/>bind: 127.0.0.1 or LAN"]
Proxy -->|"rtsp://user:pwd@<br/>host:<port>/rtsp_tunnel<br/>?inst=1&enableaudio=1"| B[BlueIris]
Proxy -->|"rtsp://...?inst=1"| F[Frigate]
Proxy -->|"rtsp://...?inst=2 sub"| ICam[iobroker.cameras]
Cloud[Bosch CBS API] -.->|hourly session renew<br/>~60s before timeout| Proxy
По умолчанию прокси-сервер прослушивает...127.0.0.1 — доступен с самого хоста ioBroker, но не с другой машины. Чтобы использовать регистратор на отдельном хосте:
- Административный интерфейс → вкладка "RTSP / Поток" → поставьте галочку " Предоставить доступ к RTSP-прокси в локальной сети" .
- Установите внешнее имя хоста / IP-адрес локальной сети равным IP-адресу локальной сети хоста ioBroker, например.
192.168.1.50. - Сохранить → перезапуск адаптера →
cameras.<id>.stream_urlстановитсяrtsp://<user>:<password>@192.168.1.50:<sticky-port>/rtsp_tunnel?…. - Скопируйте этот URL-адрес в BlueIris / Frigate / ваш рекордер.
Порт сохраняет свою работоспособность после перезагрузки адаптера и обновления сессий Bosch (сохраняется вcameras.<id>._proxy_port — Укажите URL-адрес в программе для записи экрана один раз, и она будет продолжать работать.
Запись разговора с участием только человека с помощью CodeProject AI
Рабочий процесс, описанный на форуме ioBroker: добавьте каждыйstream_url В BlueIris, как в RTSP-камере, можно включить круглосуточную запись дополнительного потока с коротким сроком хранения (например, 7 дней) и интегрировать оповещения BlueIris об обнаружении движения с искусственным интеллектом CodeProject, работающим под управлением YOLO. Только когда CodeProject классифицирует кадр как человека (или другой заданный класс — собака, кошка, транспортное средство, номерной знак, лицо), BlueIris переключается на основную запись с несколькими секундами превью. Это значительно сокращает объем занимаемого места и количество ложных срабатываний, сохраняя при этом качественный основной видеоматериал для важных событий.
iobroker.cameras (снимок / плитка визуализации)
iobroker.cameras оборачивает стандартный источник RTSP в снимки JPEG и плитку Vis MJPEG (без H.264/аудио — для полноценного воспроизведения в реальном времени используйте виджет VIS-2 Camera этого адаптера или go2rtc). Он не принимает полныйrtsp://… URL в одном поле — он формируется из отдельных полей, поэтомуstream_url Необходимо разделить.
Рекомендуется: включить постоянно доступную RTSP-точку доступа. iobroker.cameras получает кадр по собственному расписанию. По умолчанию локальный RTSP-прокси прослушивает порт только во время прямой трансляции, поэтому запрос, поступивший во время выключения трансляции, попадает на закрытый порт, и iobroker.cameras отправляет соответствующие сообщения в лог.
Connection refusedВключите «Настройки» → «RTSP / Поток» → «Обеспечить постоянную доступность конечной точки RTSP» .stream_persistent_endpointЗатем адаптер постоянно поддерживает связь между прослушивателем и стабильным портом для каждой камеры и автоматически открывает сессию Bosch при подключении iobroker.cameras, освобождая её после истечения таймаута простоя — таким образом, конечная точка всегда доступна без постоянного использования одной из 3 общих сессий Bosch. После включения пропустите шаг 1;stream_url/stream_host/stream_port/stream_pathОни заполнены и стабильны с самого начала работы адаптера. Форум #84538.
-
(Требуется только в том случае, если указанная выше постоянно активная конечная точка отключена.) Включить поток: set
cameras.<id>.livestream_enabled = trueПрокси-сервер запускается иcameras.<id>.stream_urlзаселяет, напримерrtsp://127.0.0.1:8554/rtsp_tunnel?inst=1&enableaudio=1&fmtp=1&maxSessionDuration=3600. -
В
cameras.0Например, добавьте камеру, введите RTSP (стандартный тип ffmpeg-snapshot). Чтобы вам не приходилось вручную разделять URL-адрес, адаптер также публикует три части в виде готовых к вставке данных.cameras.<id>.stream_host,stream_portиstream_path:iobroker.cameras поле Скопировать из точки данных Пример Примечания IP-адрес камеры stream_host127.0.0.1Тот же хост → 127.0.0.1IP-адрес локальной сети автоматически отображается здесь, если включена опция "Предоставить доступ к RTSP-прокси в локальной сети" .Порт stream_port8554Сохраняет статус после перезагрузки. Протокол (настраивается вручную) TCP Необходимо изменить — по умолчанию в этом поле используется протокол UDP, но прокси-сервер работает только по протоколу TCP. Путь stream_path/rtsp_tunnel?inst=1&enableaudio=1&fmtp=1&maxSessionDuration=3600Включена строка запроса — скопировано дословно. Имя пользователя / Пароль — (оставить пустым) Прокси-сервер прозрачно внедряет аутентификацию Bosch Digest; учетные данные не требуются. -
Сохранить. iobroker.cameras предоставляет снимок по адресу
http://<iobroker-host>:8082/cameras.0/<camera-name>(используйте этот URL в виджете Vis Basic-Image) и предлагает отображение MJPEG-изображений в реальном времени через встроенный виджет Vis.
Поскольку оба адаптера обычно работают на одном и том же хосте ioBroker,127.0.0.1 Работает напрямую — Предоставление доступа к RTSP-прокси в локальной сети необходимо только в том случае, если iobroker.cameras работает на другом компьютере.
Разработка
npm install
npm run build # tsc → build/
npm run watch # auto-rebuild on save
npm test # unit tests (1480+ passing)
npm run lint
npm run test:coverage # coverage report → coverage/index.html (HTML) + lcov
npm run test:coverage:check # enforce thresholds: 80% lines/functions, 70% branches
CI/CD и тестирование
Полный конвейер тестирования — уровни тестирования (lint → модульное тестирование + анализ покрытия кода → проверка пакетов → CodeQL/gitleaks/dependency-review → интеграция адаптера → repochecker → дымовая проверка релиза), все рабочие процессы GitHub Actions и процесс выпуска — документирован с помощью диаграмм в [ссылка на документацию].docs/ci-cd.md Стандарты качества и развитие ioBroker от последней версии до стабильной находятся в процессе разработки.docs/TESTING_AND_QUALITY.md .
Уровень безопасности (GitHub Actions): CodeQL (SAST), gitleaks (сканирование секретов), dependency-review + Dependabot , с правами доступа в рамках рабочего процесса по принципу минимальных привилегий.
Развертывание вручную на локальном тестовом экземпляре ioBroker.
SRC=$(pwd)
DST=$HOME/iobroker-test/node_modules/iobroker.bosch-smart-home-camera
rm -rf "$DST/build" && cp -r "$SRC/build" "$DST/"
cp "$SRC/io-package.json" "$DST/"
cp -r "$SRC/admin" "$DST/"
~/iobroker-test/iob upload bosch-smart-home-camera
~/iobroker-test/iob restart bosch-smart-home-camera.0
Существующая ландшафтная конфигурация адаптеров
- iobroker.bshb — Локальный REST API для SHC (термостаты, переключатели, сигнализация). Только включение/выключение камеры, потоковая передача или создание снимков недоступны. Активный разработчик.
- iobroker.cameras — универсальный HTTP-адаптер для создания снимков и передачи RTSP-трафика. Используйте этот адаптер в паре с другими адаптерами.
stream_urlИспользуйте параметр `state` в `iobroker.cameras` для получения плитки Vis — см. `iobroker.cameras` (снимок / плитка Vis) для настройки каждого поля отдельно. - iobroker.onvif — универсальный ONVIF-адаптер. Камеры Bosch в настоящее время не предоставляют локальную ONVIF-точку доступа, поэтому этот адаптер является единственным способом подключения оборудования Bosch.
Процесс выпуска
Этот адаптер использует@alcalzone/release-script для обновления версий.
npm run release patch # 0.3.0 → 0.3.1
npm run release minor # 0.3.0 → 0.4.0
npm run release major # 0.3.0 → 1.0.0
- Создает и запускает полный набор тестов (тесты должны пройти проверку).
- Версия с улучшенными характеристиками в
package.json+io-package.json - Автоматически генерирует новость на основе коммитов, внесенных после последнего релиза.
- Создает
vX.Y.ZДобавление тегов и отправка изменений — GitHub Actions автоматически публикует контент в npm.
Связанные проекты
Часть семейства из пяти реализаций для умных домашних камер Bosch (плюс альфа-версия интерфейса):
| Выполнение | Репо | Статус |
|---|---|---|
| 🏆 Интеграция с Home Assistant | Bosch-Smart-Home-Camera-Tool-HomeAssistant | v14.4.1 · HA Quality Scale Platinum · готово к использованию в производстве |
| 🐍 Интерфейс командной строки Python | Bosch-Smart-Home-Camera-Tool-Python | v10.10.4 · Мини-NVR + загрузка по SMB (БЕТА) · Резервный режим работы по локальной сети (ping / --local) · Предустановки PTZ · Доставка веб-хуков · Захват / Исследование / Автономный режим |
| 🟢 Адаптер ioBroker (этот репозиторий) | ioBroker.bosch-smart-home-camera | v1.8.2 · стабильная версия · npm · RTSP-интерфейс без учетных данных (постоянно включенный) · уровень управления облачным API WRITE (зоны/маски/правила/совместное использование/прошивка) · счетчики ежедневных событий · мост MQTT · предустановки PTZ · виджеты VIS-2 (одиночный + обзорный) |
| 🤖 Сервер MCP | Bosch-Smart-Home-Camera-Tool-MCP | v1.5.5 · cred-rotation · Предустановки PTZ · Привязка сертификатов TOFU · LAN-ping + prefer_local · Интеграция с Claude Code / Claude Desktop |
| 🔴 Узлы Node-RED (альфа) | Bosch-Smart-Home-Camera-Tool-NodeRED | v0.2.5-alpha · облачные узлы (события / снимки / конфиденциальность / URL потока / конфигурация) |
Также: Bosch Smart Home Camera — Python Frontend (NiceGUI) — v0.1.5-alpha (панель управления + подробная информация о камере + настройки) — приветствуется участие сообщества
HA остается эталонной реализацией — функции сначала появляются именно там; Python CLI, адаптер ioBroker и сервер MCP догоняют ее со временем.
Changelog
1.8.3 (2026-07-15)
Docs-only release: fixed the MCP row in the shared Integration Comparison table (shares the Python CLI's bosch_config.json rather than its own OAuth2 PKCE flow) and a broader README accuracy pass (state tree, config options, RTSP front-door emphasis). No functional changes.
1.8.2 (2026-07-14)
Docs-only release: refreshed the sibling-repo version table in the README. No functional changes.
1.8.1 (2026-07-13)
Performance/reliability fix: local camera (digest auth) and cloud API HTTPS requests now reuse pooled keep-alive connections instead of opening a fresh TCP+TLS connection per request, cutting per-request latency and connection overhead. Also fixes a related agent-cleanup gap so pooled connections are properly torn down on adapter unload instead of leaking sockets. No functional/state changes.
1.8.0 (2026-07-11)
New: cloud-API WRITE for the management tier, closing a feature-parity gap with the HA integration and Python CLI (same /v11 endpoints, byte-verified against both). Writable states per camera: motion_zones_set/privacy_masks_set (POST array of {x,y,w,h}, [] clears all), rule_create/rule_update/rule_delete (automation rules), firmware_install (button — installs the pending firmware update, guarded against a double-press or an already-in-progress install). Gen2 only: camera_share, friend_invite, friend_remove. New read-only firmware status states: firmware_current_version, firmware_latest_version, firmware_update_available, firmware_updating. This is cloud write only — the on-device RCP zone/mask editor stays parked pending broader local write access from Bosch. Also adds a blocking npm audit --omit=dev CI gate ahead of the deploy job. 38 new tests, full suite 1367 → 1405 passing, coverage gate green.
1.7.8 (2026-07-07)
Docs-only release: repository-checker keyword fix (package.json/io-package.json, PR #46), refreshed sibling-repo version references in the "Related Projects" table, dev-sandbox Node version doc fix, devDependency bumps (@types/node, @iobroker/adapter-react-v5). No functional changes.
1.7.7 (2026-07-03)
ioBroker.repositories PR#5983 manual-review hardening (mcm1957, 2026-07-02): log/notification text is English-only now (was German, leaking untranslated into this.log.*); external camera IDs are sanitized (ioBroker FORBIDDEN_CHARS) before use in object paths; removed the dead region config option (EU/US dropdown had no effect — CLOUD_API is, and remains, hardcoded); README now credits/links Bosch Smart Home; minor dead-code cleanup (_maskCreds, _featureFlagsCache, EVENT_POLL_INTERVAL_MS). mqtt_password protectedNative/encryptedNative confirmed correct at the io-package.json root (already in place; a first attempt moved them under common, which @iobroker/repochecker's schema rejects — reverted before release). New regression tests pin all of the above. No functional/behavioral change for existing installs beyond the language fix.
1.7.6 (2026-06-28)
CI: integration test harness (@iobroker/testing), build job, Node 22/24 matrix, coverage gate (≥80%), i18n E5606 gate. No functional changes.
1.7.5 (2026-06-25)
Cross-version port of Home Assistant v13.7.8–v13.7.9 WebRTC stability fixes.
- Stale-PC guard (fix): after a WebRTC reconnect, late
muteevents from the old peer connection no longer trigger a new recovery — ending an endless loop where every reconnect caused another one. - getStats freeze oracle (fix): the player now checks
framesDecodedviagetStatsevery 5 s to catch a go2rtc silent stall or a Chrome 145 muted-background-pause that the existing frame-callback / stall timer may not see. - Dead-track CGNAT detection → sticky HLS (fix): when WebRTC connects but delivers zero decoded frames (bytes flowing = decoder stall; no bytes = CGNAT cut), the player escalates to HLS for the rest of the session instead of retrying WebRTC in an endless loop.
- iOS native-HLS 8s watchdog (fix): Safari/iOS AVPlayer can hang at load with no self-recovery; a watchdog hard-reloads the element if
playingdoes not fire within 8 s. - Faster reconnect (improvement): recovery restart delay reduced from 2000 ms to 1000 ms.
1.7.4 (2026-06-23)
FCM push reliability: periodic 24 h re-registration prevents silent push loss on long-lived sessions.
1.7.3 (2026-06-21)
Cross-version port of the Home Assistant v13.7.5 fix.
- Picture-in-Picture freeze in a background tab (fix): follow-up to 1.7.2. With the live stream floating in Picture-in-Picture and the browser tab left in the background, the floating window could still freeze for up to a minute before recovering, because Chrome throttles the player's periodic freeze-check timer to about once a minute in a hidden tab. The player now drives that check from a Web Worker, which runs on a separate thread Chrome does not throttle, so a frozen Picture-in-Picture stream is detected and reconnected in about ten seconds instead of up to a minute. The worker only acts on a Picture-in-Picture window you are actively watching (a plain hidden tab is left alone to conserve the camera session) and falls back cleanly to the existing timer where Web Workers are unavailable. Also hardens the freeze check so a slow reconnect's first frame can't briefly look frozen.
1.7.2 (2026-06-19)
Cross-version port of the Home Assistant v13.7.4 fix.
- Picture-in-Picture freeze after a tab switch (fix): with the live WebRTC stream floating in Picture-in-Picture (vis-2 widget overlay), switching to another browser tab for a while could freeze the floating window; returning to the tab resumed the in-page video but the floating window stayed frozen. A hidden tab heavily throttles the player's periodic stall check, and the underlying go2rtc WebRTC stream can quietly die in the background. The player now detects a freeze without that throttled timer — it watches for presented video frames (which keep flowing to a Picture-in-Picture window even while the tab is hidden) and listens for the WebRTC track going silent or the connection failing, then reconnects into the same floating window automatically with no interaction. The reconnect reuses the existing video element so Picture-in-Picture picks the stream straight back up.
1.7.1 (2026-06-18)
- Daily counters now bucket by local date (fix):
events_today,movement_countandaudio_countwere bucketed by UTC day, but Bosch event timestamps carry an explicit timezone offset (e.g.+02:00[Europe/Berlin]) — so events in the hours around local midnight were counted on the wrong day and the counters rolled over at UTC midnight instead of local midnight. They now bucket by each event's local calendar date, matching the Home Assistant integration (issue #34).last_motion_atand event freshness were already correct.
1.7.0 (2026-06-18)
Cross-version round porting the latest Home Assistant integration features and fixes.
- Daily event counters (new): per-camera
events_today,movement_countandaudio_countdatapoints, derived from the cloud event list and bucketed by UTC day (mirrors the HA sensors; UTC avoids the mis-count around local midnight). Refreshed on every poll so they roll over at UTC midnight without needing a new event. - BoschOverview widget — live stream + status: the expanded (click-to-enlarge) overlay now plays live WebRTC/HLS via go2rtc (grid tiles stay snapshot so the camera's ~3-session limit is respected), with a snapshot fallback on stream error. Added a cloud maintenance banner above the grid and a last-event timestamp badge per tile.
- Widget reliability: per-camera volume/mute localStorage keys (multiple cameras no longer overwrite each other's volume); a second tile of the same camera auto-mutes the first (different cameras stay independent); offline/privacy tiles now show the last good frame as a dimmed backdrop instead of a black box.
- Backend fixes: concurrent snapshot triggers for the same camera are coalesced onto one session/fetch (no double-open); a camera stays online during an active cloud-maintenance window while it is still locally streaming, instead of being flipped offline by the maintenance-related snapshot failures.
1.6.1 (2026-06-16)
- FCM push reliability: the motion-event safety-net poll is no longer suppressed after a failed cloud fetch. A transient cloud hiccup during a push used to stamp the defer-timestamp before the fetch succeeded, keeping the safety poll quiet for up to 5 minutes and delaying motion detection. The defer-timestamp now advances only after a definitive response (+3 regression tests). Cross-version of the Home Assistant integration's event-poll fix.
1.6.0 (2026-06-15)
Cross-platform reliability round for the BoschCamera VIS-2 widget and the adapter, driven by a structured bug-hunt (Chrome, Safari, Firefox, Edge on macOS, Windows, iOS, Android, Linux).
- iOS Picture-in-Picture now works: the widget falls back to the WebKit presentation-mode API where the standard PiP API is unavailable, and leaves PiP correctly when the stream stops.
- Touch-friendly volume: the volume control is reachable by tap (it was hover-only); audio recovers after the browser/AudioContext is interrupted by Android backgrounding or doze.
- Reconnect fixes: a Picture-in-Picture listener leak on re-start is fixed, a conflicting
mutedprop no longer fights the imperative mute control, and the control pill-bar scrolls instead of clipping on narrow screens. - Adapter robustness: the motion-event safety-net poll now survives an FCM push reconnect (it could previously be cancelled and never re-armed, freezing motion timestamps), and several shutdown-time timer warnings were eliminated.
1.5.7 (2026-06-15)
Cross-version parity with the Home Assistant card v13.5.17 — live-stream reliability + quieter controls for the BoschCamera VIS-2 widget.
- Live sound survives an auto-reconnect: the stream no longer comes back muted after a stall / HLS-fallback / session refresh (the shared AudioContext keeps the unmute intent across reconnect; the pause-guard remains the safety net).
- Tab-switch & bfcache recovery: the live (WebRTC) stream now restarts when the page returns to the foreground or is restored from the browser's back/forward cache (
pageshow/visibilitychange), instead of staying frozen. - Quieter controls: the audio and Picture-in-Picture buttons appear only while a live stream is playing (hidden over an idle/snapshot tile). Card corners no longer flicker on re-composite (
isolation: isolate). - WebRTC robustness: ICE
disconnectedis treated as transient (onlyfailedfalls back to HLS, no more premature downgrade); audio/video tracks are accumulated into one MediaStream (no srcObject re-assign flash); a leakedplaying/pauselistener on WebRTC→HLS fallback is fixed; a light stall-checker re-plays a live<video>the browser paused in the background. - Maintenance banner is dismissable with an × (per browser session). Privacy placeholder now shows the last-event time.
1.5.6 (2026-06-14)
Picture-in-Picture for the VIS-2 camera widget (live WebRTC view).
- Picture-in-Picture: a new button in the BoschCamera widget's control bar floats the live WebRTC stream into the browser's always-on-top window — over every app on macOS Safari, over the browser on Chrome. The floating window's title shows the camera name (via the Media Session API).
- Single-PiP greying: the browser allows only one PiP window at a time, so while one camera is floating, the PiP button on every other BoschCamera widget on the view greys out; it lights up on the active one and re-enables for all when PiP closes.
- The window keeps playing across a stream reconnect, and the button is hidden where the browser lacks PiP support (most iOS/Android WebViews; snapshot/MJPEG modes). New tooltip strings added in all 11 UI languages.
1.5.5 (2026-06-13)
Settings-page reorganisation, German translation polish and concurrency hardening for the always-on RTSP endpoint.
- Settings page reorganised into tabs: Connection · RTSP / Stream · Events / Notifications · API requests / Power saving · MQTT Bridge. The always-on RTSP endpoint option (
stream_persistent_endpoint, still opt-in / default off) moved from the Power saving tab to RTSP / Stream, next to the other external-recorder settings (LAN exposure, external host, max session duration) where it belongs. - German translations polished: the stream-settings labels/help that shipped machine-translated in v1.5.4 (e.g. "Freigabesitzung nach Leerlauf(en)") are now natural German.
- Concurrency hardening: two recorders connecting to the same camera's always-on endpoint at the exact same moment now share a single
ensureLiveSessioninstead of racing to open two Bosch sessions (one of the 3 shared slots could previously be wasted). +15 regression tests.
1.5.4 (2026-06-13)
New: optional always-on RTSP endpoint for external recorders (iobroker.cameras, BlueIris, Frigate).
- Always-on RTSP endpoint (
stream_persistent_endpoint, opt-in, default off): the local RTSP proxy previously listened only while a live stream was running. An external recorder such as iobroker.cameras polls the RTSP URL on its own schedule, so a poll that landed while the stream was off hit a closed port and the recorder loggedConnection refused(forum #84538). When the new option is enabled (Settings → RTSP / Stream), the adapter keeps a lightweight TCP listener bound on a stable per-camera port at all times. The Bosch session + TLS proxy are opened on demand the moment a recorder connects and released again afterstream_persistent_idle_timeoutseconds (default 60 s) with no client — so the endpoint is always reachable without permanently occupying one of the 3 shared Bosch sessions.stream_url/stream_host/stream_port/stream_pathstay populated and stable from adapter start. A live stream the user explicitly enabled (livestream_enabled = true) is never auto-released.
1.5.3 (2026-06-12)
Fix: Bosch cloud connection failed to start after the v1.5.1 TLS hardening.
- Cloud TLS partial-chain fix: v1.5.1 pinned only the Bosch "Video CA 2A" intermediate certificate. Node.js (unlike the Python/HA integrations) has no equivalent of OpenSSL's
PARTIAL_CHAINflag, so it could not anchor the certificate chain at the pinned intermediate and every Bosch cloud handshake failed withunable to get issuer certificate. On systems without a valid persisted camera state this blocked camera discovery on startup ("No persisted camera state found — cannot start"). The adapter now verifies cloud certificates by checking the hostname, validity and that the leaf is either signed by the pinned Bosch CA or chains to a trusted system root (used by the Let's Encrypt OAuth host). MITM protection from v1.5.1 is fully preserved — self-signed, expired, hostname-mismatch and untrusted-root certificates are still rejected.
1.5.2 (2026-06-11)
Automatic cleanup of orphaned camera object subtrees.
- Orphaned camera objects pruned on start: removing a camera from the Bosch account previously left behind a
cameras.<uuid>object subtree in ioBroker with no way to clean it up without manual object deletion. The adapter now detects these orphaned subtrees on each successful camera fetch and removes them automatically. A safety guard prevents any deletion when the cloud fetch returns an empty list (e.g. during a cloud outage), so no active camera data is lost.
1.5.1 (2026-06-11)
Security: TLS certificate verification for Bosch cloud and proxy connections.
- TLS certificate verification (CWE-295): the cloud API calls and the video proxy tunnel now validate the private Bosch CA instead of accepting any certificate, closing a potential MITM gap for OAuth tokens on the local network. Local camera endpoints are not affected.
1.5.0 (2026-06-10)
Fixes motion silently freezing, plus a configurable stream session length and an opt-in idle-stream reaper.
- Fix — motion / snapshots no longer silently freeze after a while (forum #84538): the cameras kept detecting motion in the Bosch app, but
last_motion_at/last_event_image_atstopped updating and only an adapter restart brought them back. Root cause: the FCM push library does not surface a raw TCP socket death (its health check stays "connected"), and event polling was only ever started when FCM failed at startup — so a silently-dead push connection left motion frozen indefinitely. Like Home Assistant, the adapter now runs an always-on safety-net event poll: it fetches events roughly every 5 minutes while FCM looks healthy, and every poll interval once FCM is known to be down, so motion is never missed for longer than the safety window regardless of FCM. - New setting — stream
maxSessionDuration(RTSP / Stream tab,0= camera default, range 600–21600 s): a continuous go2rtc / recorder pull could drop with a timeout at the camera's 3600 s session boundary before the adapter's renewed session took over. Raise this (e.g. 5000) to keep the stream running longer between renewals, without editing the URL by hand. - New setting — turn off unwatched live streams (API requests / Power saving tab, opt-in, default off, experimental): an enabled live stream keeps occupying one of the 3 shared Bosch sessions even when nobody is watching. When enabled, the adapter reads how many clients are actually pulling the local RTSP proxy and, after the configured idle timeout with none, turns the live stream off to free the session. A stream that something is really watching is never stopped.
- New settings — diagnostic polling (API requests / Power saving tab): a Poll diagnostic datapoints switch (default on) and a separate Diagnostic poll interval (default 300 s, range 60–7200 s). The rarely-changing diagnostics — motion zones, light/ambient config, alarm settings, ONVIF/RCP info and cloud feature flags — can now be slowed down or turned off entirely to cut cloud requests, independently of the main poll interval. The core states (online, privacy, motion, snapshots, light, livestream) are unaffected.
- Quieter log: the RTSP Digest-rotation
401(expected, self-healing churn when Bosch rotates the stream credentials and the client reconnects) is now logged at debug instead of warn.
1.4.1 (2026-06-10)
Options to reduce load on the shared Bosch session limit, plus dependency updates.
- New "API requests / Power saving" settings tab. Your cameras share a hard limit of only 3 simultaneous Bosch sessions across the Bosch app, Home Assistant, this adapter and any recorder, and the cloud is polled per camera — the new options let you cut that load. Request-heavy options are off by default on a fresh install; motion, manual snapshots and on-demand live streams keep working regardless.
startup_snapshot(default off): the adapter no longer opens a Bosch session per camera at start just to learn the online state. Online/offline is now resolved the cheap, session-less way (a LAN TCP ping, falling back to the cloud/pingand/commissionedchecks). Turn it on to fetch a real boot image per camera.poll_interval(default 60 s, range 30–3600 s): configurable cloud poll cadence. Each tick is several cloud requests per camera, so raising it reduces request volume roughly proportionally; motion push (FCM) stays near-instant.- Widget "Auto-refresh indoor snapshot" (default off): the indoor snapshot pulse (360° every 5 s, Gen2 indoor every 10 s) is now opt-in per widget, so a dashboard tile no longer repeatedly opens a Bosch session unless you ask it to.
- Dependencies:
axios1.16.1 → 1.17.0 (security hardening) and@aracna/core1.4.4 → 1.5.0 (matches the@aracna/fcmpeer requirement).
1.4.0 (2026-06-10)
A second multi-camera widget, the single-camera card brought to Home Assistant parity, and two tile fixes.
- New "Bosch Camera Overview" VIS-2 widget: a multi-camera grid that discovers every camera automatically, sorts them into online / privacy / offline tiers, shows a snapshot and per-tile quick controls, and expands a tile to the full card on click.
- Single-camera card brought to Home Assistant parity: the WebRTC iframe is replaced by a native
<video>element (go2rtcRTCPeerConnectionwith an HLS fallback), which adds an audio toggle, a volume slider, a pause-guard and digital zoom. The full control set is now reachable through a catalog-driven bottom-sheet (gear button) instead of a fixed list, with model-gated pan, motion-zone/privacy-mask overlays and status badges. - Privacy cameras now report
onlinecorrectly: a reachable camera in privacy mode no longer shows as offline. The state is reconciled from the cloud (LAN-TCP → ping → commissioned) so the tile shows "Online" / a privacy placeholder instead of a false "Offline". - Fix — no broken-image flash when leaving privacy mode: turning privacy off briefly showed the browser's broken-image glyph before the first frame loaded. A loading veil now covers the snapshot until a real frame arrives, and the image is refetched immediately on the privacy reveal.
- Fix — indoor tiles auto-refresh their snapshot: the cached snapshot only updated on motion, so a panning or busy indoor camera looked frozen. Indoor tiles now pull a fresh snapshot while visible (Gen1 360° every 5 s, the indoor model every 10 s); outdoor cameras are unchanged.
1.3.0 (2026-06-08)
New VIS-2 camera widget (React) with live video, plus a livestream-stability fix.
- New VIS-2 "Bosch Camera" widget (React / Module Federation): drop it on any VIS-2 view. Three stream modes — snapshot (near-live image), live MJPEG (started by the play button, streamed from the local RTSP proxy), and go2rtc WebRTC (low-latency + audio). iOS/Android-style frosted control bar with privacy, livestream, light, snapshot, pan and siren buttons; actions are gated while privacy is on (only the privacy toggle and fullscreen stay active). Pan is shown only on the Gen1 360° indoor. Fullscreen renders via a portal so it always covers the whole screen, and offline cameras get a clear "Offline" state.
- Fix: the RTSP proxy is no longer torn down ~60 s after start when the livestream is enabled during a snapshot (a race armed the snapshot idle-teardown with a stale flag), so VLC/recorders/the widget no longer get "connection refused".
1.2.7 (2026-06-07)
Easier integration with the ioBroker.cameras adapter.
- New per-camera datapoints
stream_host,stream_port,stream_path: the live-stream URL is now also published as three separate read-only fields. The generic RTSP camera type in the ioBroker.cameras adapter has no single full-URL input, so these can be pasted field by field without splittingstream_urlby hand (forum request). They are populated alongsidestream_urlon stream start and cleared on teardown and on privacy-driven credential rotation. - README: added an "External recorders → ioBroker.cameras" how-to with the field-by-field mapping (set Protocol to TCP — the proxy is TCP-only).
1.2.6 (2026-06-07)
Object-structure roles corrected for the ioBroker repository review.
- Invalid
common.rolevalues fixed (repochecker object-structure check E1008/E1009): status states (info.fcm_active,info.connection_status,info.maintenance.state) now useinfo.status; ISO-8601 timestamp states (last_motion_at,last_event_image_at, …) usedateinstead ofvalue.time(which only allowsnumber); writable string selects (stream_quality,motion_sensitivity,detection_mode) usetextinstead of the non-cataloguelevel.mode; JSON diagnostics (onvif_scopes,cloud.feature_flags) usejson; the WiFi signal percentage usesvalue; the pan angle useslevel; the string event id (last_seen_event_id) usestextinstead ofvalue. - Automatic one-time migration: on first start of 1.2.6 existing installations have these roles rewritten in place (idempotent), so no manual object cleanup is needed.
1.2.5 (2026-06-04)
Stream setup is easier to discover.
- Empty
stream_url/ go2rtc "connection refused": the livestream is opt-in and OFF by default, so on a fresh installstream_urlstays empty and a go2rtc / recorder pointed at the not-yet-listening proxy port getsconnection refused, with nothing to signal why (forum #84538). The adapter now logs a one-time, actionable hint at startup while no camera streams (setcameras.<id>.livestream_enabled=true; enable "Expose RTSP proxy to LAN" if go2rtc runs on another host), thestream_urldatapoint name states it stays empty untillivestream_enabled=true, and the README has a new troubleshooting section. No behaviour change — streaming was always opt-in.
1.2.4 (2026-06-04)
Adapter icon fix.
- Adapter icon: the admin icon was a solid blue placeholder; replaced it with the real red Bosch camera logo (the blue tile had shown in the ioBroker admin and in the adapter catalogue).
1.2.3 (2026-06-04)
Session-quota log noise + snapshot retry hardening.
- HTTP 444 session-quota: when a camera shares Bosch's hard 3-session limit with the mobile app or another integration (Home Assistant / Python CLI), a 444 recurs every 60 s. The handler now warns once per 5-minute window (subsequent hits at
debug), fires the "close other clients" advisory only when first crossing the threshold, and caps the auto-retry loop at 5 attempts — after that it logs a single info line and resumes on the next motion event / manual snapshot instead of looping forever. - Snapshot after motion: the
snap.jpgretry now does up to 2 attempts with increasing backoff (0.8 s, 1.6 s) instead of one, so an empty/aborted image in the first moment after a motion trigger (camera still warming the stream) no longer fails.
1.2.2 (2026-06-04)
Log-noise cleanup + Home Assistant polling parity.
- Privacy HTTP 442: the per-camera motion-config poll returned
442(privacy mode / settings frozen) on every slow-tier tick for a camera in privacy mode, and logged aMotion config poll failedline each time.442is now treated like443— a benign "keep last value" skip, no log. - MJPEG fast-path: soft FFmpeg failures (non-zero exit / empty / non-JPEG output — all of which fall back to
snap.jpg) dropped fromwarntodebug, and the MJPEG path is now disabled for a camera after 2 consecutive failures this session (no more FFmpeg spawn + fallback on every snapshot for cameras whose RTSP sub-stream rejects it). - First-snapshot abort: the expected Bosch "stream has been aborted" on the first
snap.jpgafter idle is now logged atsilly(it always retries). - Empty snapshot after motion: an empty
snap.jpgbody right after a motion trigger (camera still warming the stream) is now retried instead of failing. - Shutdown: timers no longer re-arm during
onUnload, removing thesetTimeout called, but adapter is shutting downwarnings. - Polling interval: the event-poll fallback and the camera-state base tick are now 60 s (was 30 s), matching the Home Assistant integration's default
scan_interval; the slow diagnostic tier still lands at 300 s.
1.2.1 (2026-06-04)
FCM push fix.
Push registration failed with HTTP 401 UNAUTHENTICATED at the Google FCM Registrations API, so the adapter fell back to event polling every 30 s. Cause: the web-push registration sent the well-known default Chrome VAPID key as applicationPubKey, which Google rejects — the registration token used to receive Bosch push was therefore never issued. Fixed by omitting the default VAPID (applicationPubKey: null), matching the Home Assistant / Python client. Push now registers reliably and motion/person/audio events arrive instantly instead of with up to 30 s delay.
Also added a self-heal: when persisted FCM credentials are rejected by Google on start, the adapter retries once with a fresh registration before falling back to polling.
Offline-camera handling: an offline camera can never serve a stream, so the first live-session attempt hit Bosch's shared session quota (HTTP 444) and the adapter then retried every 60 s forever, spamming the log and burning the 3-session budget shared with the Bosch App / other integrations. The 444 handler now confirms the camera's status with a session-less probe (LAN ping, then cloud /ping / /commissioned, mirroring Home Assistant); a genuinely offline camera is marked online=false and the retry loop stops, while a real quota contention on an online camera still retries.
1.2.0 (2026-06-03)
Management-tier read-only datapoints (Home Assistant parity).
New per-camera datapoints under cameras.<id> (all read-only):
- Motion zones:
motion_zones(raw JSON array of{x,y,w,h}) +motion_zones_count. - Privacy masks:
privacy_masks(raw JSON) +privacy_masks_count. - Automation rules:
rules(raw JSON array of{id,name,isActive,startTime,endTime,weekdays}) +rules_count. - Floodlight schedule (Gen1 only):
lighting_schedule_status(thescheduleStatusmode) +lighting_schedule(raw JSON fromlighting_options). Gen2 already exposesambient_light_schedulevia/lighting/ambient. - Friend sharing (Gen2 only):
shared_with_friends(raw JSON array) +shared_with_friends_count. Gen1 cameras do not expose this endpoint.
These are polled on the slow tier (~every 300 s) and are best-effort: HTTP 404/442/443/444 keep the last-known value and never raise. The matching write paths (zone/rule/share editing) are intentionally not wired yet.
Internal: global eslint . is now clean (widgets linted against real browser/VIS globals instead of being ignored).
1.1.0 (2026-06-02)
Feature + hardening release.
New features (Home Assistant parity + ioBroker-native):
- Local HTTP snapshot server (
snapshot_http_port, roleurl.cam) so VIS image widgets / the type-detector can load the latest JPEG per camera, plus asendTo("bosch-smart-home-camera.0", "snapshot", {camId|name})command returning the JPEG as buffer/base64 for Telegram/Signal/Pushover. - Push notifications: global on/off (
notifications_enabled) and six per-type toggles (notify_movement/_person/_audio/_trouble/_camera_alarm/_trouble_email). - Motion:
motion_enabledon/off +motion_sensitivityselect;detection_modeselect (Gen2: all_motions / only_humans / zones);record_sound. - Gen2 Indoor II alarm system:
alarm_arm,alarm_mode,pre_alarmswitches +alarm_statesensor. - LEDs / overlay:
status_led(Gen2),timestamp_overlay,power_led_brightness(Gen2 Indoor); Gen2 Outdoor lighting:motion_light_enabled+motion_light_sensitivity,ambient_light_enabled+ambient_light_schedulesensor. intercom_enabledtwo-way audio (Gen2);commissionedstatus sensor; all new admin strings translated into 11 languages.
Stability fixes (several mirrored from the Home Assistant integration):
- FCM push no longer dies permanently after the hourly token refresh (the listener's bearer token is now kept current).
- Stream session-renewal hardening: a stream torn down during a renewal can no longer be resurrected (generation guard), emergency/on-demand sessions get a proper start time, and an external privacy toggle now stops the watchdog so no Bosch session leaks.
- Snapshot HTTP server closes cleanly on unload (keep-alive clients), the cached frame is published before the path so reactive consumers don't 404, and a 444 session-quota retry now reschedules instead of getting stuck.
- A CBS push-registration failure now falls back to event polling instead of leaving the adapter without any event source; Digest auth sends
cnonceonly whenqopis present (RFC 7616); the duplicate-event guard now covers both the push and the polling path.
Internal: npm run test:fast (parallel mocha) for ~5× faster local runs; ~28 new regression tests (full suite 1092 passing).
1.0.5 (2026-06-01)
intrusion_sensitivitynow acknowledges the clamped 0-7 value instead of the raw input (mirroringintrusion_distance, fixed in 1.0.3), so the datapoint never shows a sensitivity the camera did not actually receive.
1.0.4 (2026-05-31)
Internal hardening release, no functional changes:
- All polling and watchdog timers (event poll, state poll, maintenance poll, session-renewal, LAN ping, snapshot retry) are now created through the adapter-core
setInterval/setTimeout, so the adapter core cancels them automatically on unload — no orphaned timers outlivingonUnload. HTTP fetch timeouts now useAbortSignal.timeout(). - New CI security layer: CodeQL static analysis (Python and JavaScript/TypeScript), gitleaks full-history secret scanning, and a dependency-review gate, plus least-privilege
permissionson every workflow and adocs/ci-cd.mdpipeline document. - README restructured to match the Home Assistant project layout; copyright line switched to ASCII
(c)(repository-checker E6033).
1.0.3 (2026-05-29)
Write-path fixes (cross-version with the Home Assistant integration and Python CLI), live-verified on the dev sandbox against firmware 9.40.102:
- Intrusion detection distance now clamps to 1–8 m. The camera rejects values above 8 with HTTP 400, so writing
intrusion_distance= 9 or 10 previously failed withFailed to handle intrusion_distance … status code 400. The datapoint maximum, label and acked value now all reflect the 1–8 range. - Intercom audio levels are written as the full
{audioEnabled, microphoneLevel, speakerLevel}body (read-merge-write). Settingspeaker_levelno longer silently wipesmicrophone_level. - Pan acks the clamped angle that was actually written instead of the raw user value, and a busy camera (HTTP 444, too many simultaneous live sessions) is now reported as a session-quota warning instead of a hard error.
1.0.2 (2026-05-29)
Removed the @aracna/fcm registration log noise: the library no longer prints raw postAcgRegister / PHONE_REGISTRATION_ERROR lines to the ioBroker log on every push-registration attempt — its internal loggers (which run through @aracna/core's Logger) are disabled at import. FCM health is still reported via info.fcm_active. As a side effect this references @aracna/core explicitly in source, satisfying repository-checker W5060. No functional changes.
1.0.1 (2026-05-29)
Repository-checker compliance hotfix: news entries translated into all 11 languages (E1054); current version listed in the README changelog (E6006); changelog consolidated into the README, with old entries archived in CHANGELOG_OLD.md (W6017/W6018/W6020); prettier config added (W0076); admin and vis-widget i18n completed for all 11 languages and migrated to the short {lang}.json format (W5612/W5603/S5601); obsolete eslint devDependencies dropped (W0078); dependencies refreshed — axios, axios-cookiejar-support, typescript, c8, eslint — and a @tsconfig/node22 base added (W0083/S0085/S0088). No functional changes.
1.0.0 (2026-05-28)
Out of beta. v0.9.0 features — privacy_sound_enabled, autofollow_enabled (360° cameras), unread_events_count + mark_all_read button, last_seen_event_id persisted across restarts — plus v0.9.1 follow-up fixes: 442-unsupported-feature cache (no warn-storm for the Outdoor privacy_sound poll), unread count sourced from GET /v11/events (the listing's numberOfUnreadEvents field proved unreliable), and exponential backoff (30→300 s) on WiFi / autofollow / privacy-sound polls returning HTTP 444.
0.8.0 (2026-05-25)
HA-feature parity wave — ONVIF Scopes, RCP version, cloud feature flags, MJPEG inst=3 snapshot, 444 session-quota proper sensor state. Repochecker bot preflight added (E1032 news count ≤ 7, E1105 visWidgets components, E0028 Node ≥ 22). Engines bumped to Node 22 LTS; matrix [22.x, 24.x]. @types/node pinned to ^22.0.0 (Dependabot major-version ignore added).
0.7.15 (2026-05-24)
Hotfix — upsertState cache / DB divergence.
- Symptom: sandbox running v0.7.14 showed
privacy_enabled = True ack=True ts=16:10 UTCwhile the state-poll loop kept loggingState poll: privacy ON → OFF (from cloud)every 30 s. The DPtsstayed frozen for 4+ hours despite each poll callingupsertStatewith a new value. - Root cause:
upsertStateset the in-memory_stateCacheBEFORE awaitingsetStateAsync. If the DB write failed or rejected for any reason, the cache held the new value while the DB still held the old one. From that point on every subsequentupsertStatecall hit the cache short-circuit (_stateCache.get(id) === value→ return early) and silently skipped the write — the DP was frozen on the stale DB value for the rest of the adapter's lifetime. - Fix: await
setStateAsyncfirst; only update_stateCacheafter a successful write. A failed write leaves the cache at the old value, so the next call retries instead of skipping. - +4 pinned tests in
main_upsertstate_cache_divergence.spec.tscovering: successful write updates cache; throwing write leaves cache untouched + next call retries; repeated identical writes still short-circuit; recovery after multiple transient failures. Full suite: 614 passing / 0 failing / 4 pending.
0.7.14 (2026-05-24)
Live-audit pass on the Indoor II camera surfaced eight latent bugs in the data plane, all fixed in one round.
wifi_signal_pctstuck at 0: thewifiinfoendpoint returnssignalStrengthas a percent (0–100), not dBm — verified live against firmware 9.40.102. v0.7.7 had assumed dBm semantics and looked for asignalStrengthPercentagefield that does not exist. The percent now maps towifi_signal_pctdirectly.wifi_signal_strengthDP retired: it was labelled "dBm" but always received percent values from v0.7.7 onward. v0.7.14 migration removes the DP from existing instances so users don't see two contradictory readings.trouble_disconnectno longer classified as motion: pre-v0.7.14 thefetchAndProcessEventspolling fallback wrote every cloud event — including connectivity status events (trouble_disconnect,trouble_reconnect) — intolast_motion_at/last_motion_event_typeand flippedmotion_active=true. v0.7.14 limits motion DPs to an allowlist (motion,person,audio_alarm); status events are info-logged and skipped.- Stale events no longer replay on every restart:
_lastSeenEventIdis in-memory only, so after each adapter restart the newest cached cloud event was re-processed — including four-week-oldtrouble_disconnectevents from offline Gen1 cameras. Side effects (motion_active flip, auto-snapshot, MQTT publish) are now skipped for events older than 15 minutes;last_motion_atstill updates as a historical "last motion seen" record. lan_reachablerefreshes per poll: pre-v0.7.14 the TCP-ping only fired during cloud outages, solan_reachablestayed at itsfalsedefault during normal operation. v0.7.14 fires a fire-and-forget per-camera TCP-ping inside every_pollSingleCameraStatetick (no impact on poll latency).onlineflips true under privacy mode: the snapshot-based reachability check fails when the camera is in privacy mode, soonlinestayed at the defaultfalseeven when the camera was clearly alive (TCP-pings succeed, cloud state syncs). v0.7.14 also flipsonline=truewhenever the new periodic TCP-ping succeeds.- Intrusion DPs mirror real cloud values:
intrusion_sensitivityandintrusion_distancewere never read from/intrusionDetectionConfig— they showed only the DP defaults (3, 5). New_pollIntrusionConfigruns in every Gen2 state poll, caches the full body, and mirrorssensitivity+distanceto the DPs. - Intrusion writes succeed: Bosch's
intrusionDetectionConfigendpoint rejects DELTA PUTs with HTTP 400 — pre-v0.7.14 sent{sensitivity: N}or{detectionDistance: N}. v0.7.14 reads the full config from the write-cache (or fetches it on first write), merges the user's change, and PUTs the full body. Also: thedistancefield is nameddistance, notdetectionDistance. Verified live with{"enabled":true,"sensitivity":4,"detectionMode":"ALL_MOTIONS","distance":8}→ HTTP 204. - HTTP 443 surfaces clearly: Bosch returns 443 ("non-standard") on every config-write while the camera is in privacy mode. HA already maps this to a
privacy_blockederror; v0.7.14 mirrors that and throws "cam is in privacy mode, disable privacy first" instead of a generic axios error.
Tests: existing pinned tests in main_audio_intrusion_wifi.spec.ts updated for the GET→PUT-full-body sequence and the new percent mapping; main.spec.ts polling-fallback test uses a fresh timestamp to exercise the post-stale-filter path. Full suite: 610 passing / 0 failing / 4 pending.
0.7.13 (2026-05-24)
Privacy-toggle fix part 2 — TLS proxy now actually rotates its bound Digest creds.
- Root cause of v0.7.12's residual 401: the TLS proxy held its
digestUser/digestPasswordin a closure captured at proxy-start time. On the cached-proxy reuse path (same remote, sticky port),upsertSessionrepublished the publicstream_urlwith the freshly-issued creds but never refreshed the proxy's own in-memory creds — every reconnect from BlueIris/VLC still ran the Digest dance with the pre-toggle values. - Fix (
src/lib/tls_proxy.ts):digestAuthis now stored in a mutable holder and exposed viaTlsProxyHandle.updateDigestAuth(user, password). Each per-connection auth-handler attachment reads the current values, so future connections pick up rotated creds without restarting the listener (sticky port + already-publishedstream_urlsurvive untouched). - Wire-up (
src/main.tsupsertSession): on the reuse branch,proxyHandle.updateDigestAuth(session.digestUser, session.digestPassword)is called with every session refresh. - Eager refresh (
_pollSingleCameraState): on a detected ON→OFF privacy edge, iflivestream_enabled === true, fire-and-forgetensureLiveSession()so the proxy's Digest creds are rotated before the next BlueIris/VLC reconnect attempt. Off-state edges or off-streaming cams stay no-op. - Defense-in-depth (
src/lib/rtsp_auth.ts): when the camera responds 401 to our authed retry (i.e. we still got stale creds in), the proxy now forwards the 401 honestly + ends the client socket instead of unconditionally enteringINJECTINGmode with proven-bad creds. The next client reconnect retries against the by-then-refreshed proxy. - +13 pinned tests:
rtsp_auth.spec.tscovers AUTH_RESPONDING+401 abort path;tls_proxy.spec.tscoversupdateDigestAuthAPI + idempotency;main_privacy_toggle_invalidates_session.spec.tscovers all 6 modes of the eager refresh (ON→OFF + livestream=true → fired; ON→OFF + livestream=false → not; ON→OFF + flag missing → not; OFF→ON → not regardless of livestream; ensureLiveSession rejects → no crash; unchanged state → not).
0.7.12 (2026-05-23)
Privacy-toggle invalidates cached LiveSession + clears stream_url DPs.
- Symptom: BlueIris and VLC refused to play
cameras.<id>.stream_urlafter a privacy-mode toggle via the Bosch app, returning "Check Port/User/Password" / 401 until the adapter was restarted. - Root cause: Bosch rotates the Digest credentials of the RTSP stream URL on every privacy-state edge (ON→OFF and OFF→ON). Our
_liveSessionscache holds the pre-toggle creds for up to 60 s, so the publishedstream_urlDPs kept advertising the now-stale credentials. - Fix (
_pollSingleCameraState): every detected privacy-state change drops the cachedLiveSessionand clears bothstream_url+stream_url_subDPs to"". The nextensureLiveSession()call (next stream-toggle, snapshot, RCP write, or watchdog tick) is forced to issue a freshPUT /connectionand re-publish the URLs with rotated credentials. The empty-string clear also signals to external clients that the stream is temporarily unavailable, preventing them from silently retrying the stale URL. - +4 pinned tests in
test/unit/main_privacy_toggle_invalidates_session.spec.ts.
0.7.11 (2026-05-21)
Login UX: urgency warning + tab-first workflow + README recovery steps.
- 60-second urgency warning: login dialog now displays an orange warning above the auth-code paste field emphasising that the Bosch auth code expires in ~60 seconds — prevents the most common "code expired" failure on slow copy-paste.
- Tab-first workflow: keyboard flow restructured so Tab moves directly to the paste field after opening the Bosch login tab, reducing fumble rate.
- README recovery steps: README rewritten with explicit "code expired" recovery path — what to click when the code times out mid-flow.
0.7.10 (2026-05-20)
Cloud-503 handling — honest error messages, exponential renewal backoff, maintenance-window detection. Closes #9.
- Honest error messages: 503 during active Bosch maintenance window →
[bosch-maintenance]INFO (not WARN). 401/403 → "LAN session credentials expired". "Camera offline or unreachable" only after 3 consecutive LAN TCP failures. - Exponential renewal backoff (
_handleRenewalFailure,_attemptBackoffRenewal): on watchdog renewal failure the stream stays alive and retries at 5 s → 15 s → 45 s → 120 s → 300 s → every 300 s. Only tears down after (a) session age ≥ 60 min and renewal still failing, or (b) 3 consecutive LAN TCP connect failures. - Per-camera
maintenance_stateDP (cameras.<id>.maintenance_state): string read-only, one of"active"/"scheduled"/"none". Populated by the existing hourly RSS poll and reactive 5xx re-fetches. - +9 tests in
test/unit/main_cloud_503_handling.spec.ts(all passing).
0.7.9 (2026-05-20)
MQTT Bridge.
- MQTT Bridge (
src/lib/mqtt_bridge.ts): optional publisher that connects to any MQTT broker on adapter ready and publishesmotion/person/audio_alarmevents as JSON payloads under configurable topic prefixes. Supports plain MQTT and TLS (mqtts://), optional username/password auth. Wired into all three event paths: FCM push, polling fallback, synthetic triggers. - Admin UI tab "MQTT Bridge": 6 config fields — enable toggle, broker host, port, TLS, username, password, topic prefix. All broker-detail fields hidden when bridge is disabled.
- npm dep
mqtt@^5.15.1added todependencies. - +13 tests in
test/unit/main_mqtt_bridge.spec.ts. - VIS-2 Camera Tile widget (alpha): custom
bosch-camera-tilewidget for VIS-2 dashboards — displayssnapshot_pathimage with auto-refresh, privacy-mode overlay badge, and stream URL copy button. Seewidgets/bosch-camera-tile/and## VIS-2 Camera Tile widget (alpha)section.
0.7.8 (2026-05-20)
Emergency LiveSession fix + PTZ pan presets.
- Emergency LiveSession restart: if a live-session open fails with 503 / timeout, the adapter now immediately retries once with a fresh Digest auth challenge instead of waiting for the next poll tick. Prevents a 30 s dead-stream window after transient cloud hiccups.
- PTZ pan presets (
pan_presetDP): new string data point alongsidepan_position. Accepts named presets:home,left,right,back-left,back-right. Writing a preset name triggers the same RCP pan command as the numeric position DP. Mirrors HA integration's opt-in select entity.
0.7.4 (2026-05-19)
LAN-fallback feature set.
- Coordinator outage-ping sweep: when the state-poll GET returns 5xx or fails, a throttled (once per 30 s) fan-out TCP-connect probe runs against every known camera on port 443 so
cameras.<id>.lan_reachablehas a fresh value during cloud outages. - Persistent LAN-IP map:
cameras.<id>.lan_ipis written on every successful live-session open (upsertSession). On adapter start the map is reloaded from these states so the TCP-ping path has a working address book even before the first successful cloud refresh. cameras.<id>.lan_reachablestate: boolean DP (read-only). Always reflects the last TCP-probe result; honors the post-write grace period.- Post-write grace period (30 s): after a successful local RCP write the camera briefly rotates Digest creds and tears down its HTTPS endpoint.
_localWriteAtis stamped on every successful local write;isLanReachable()treats the camera as reachable during the 30 s window so the DP does not flap tofalseafter every privacy/light toggle. - Cloud-degraded startup: when
fetchCameras()fails on startup (Bosch cloud 5xx), the adapter now rehydrates known camera IDs from the ioBroker object DB and kicks an immediate LAN-ping sweep instead of silently returning. Adapter stays alive and becomes fully operational once the cloud recovers. - Front-light Gen2 LOCAL RCP fallback:
_applyLightingState()now catches cloud errors and retries via_localWriteFrontLight()(RCP0x0c22, T_WORD, num=1, brightness 0–100). - Privacy LOCAL RCP fallback:
handlePrivacyToggle()now catches cloud errors and retries via_localWritePrivacy()(RCP0x0d00, P_OCTET) for Gen2 cameras with a known LAN IP. - +16 unit tests in
test/unit/main_lan_fallback.spec.ts. 572 tests total.
0.7.2 (2026-05-19)
Notification hooks for maintenance lifecycle and camera availability changes.
- Maintenance lifecycle notifications (scheduled → active → past): when the RSS-derived
info.maintenance.stateentersscheduled,active, orpast, the adapter writes a JSON payload to the newinfo.maintenance.last_notificationDP. Three notifications per window: announcement when first seen as scheduled, "active" when the window opens, "ended" when it closes. Deduped by(RSS link, state)so a poll tick during the same phase stays silent. - Per-camera offline / online transition notifications: when
cameras.<id>.onlineflips, a JSON payload is written to the newcameras.<id>.last_status_notificationDP. The first observation after adapter start is silent (baseline recording). Payload:{ title, message, status, ts }. - Both notification DPs are writable via Blockly
on-changetriggers: parse the JSON, extracttitle+message, and forward to Telegram, Pushover, or any other notification adapter. - +9 unit tests covering the full transition matrix, dedupe, stale-past suppression, unknown-flap silence.
0.7.0 (2026-05-19)
Cloud maintenance / outage discovery.
info.maintenance.state— string DP:active/scheduled/past/recent/unknown/idle. Classifies the latest announcement relative to the current time.info.maintenance.title,.link,.scheduled_start,.scheduled_end,.summary,.source,.camera_relevant— full parsed announcement fields.info.maintenance.last_fetched— ISO 8601 timestamp of the last successful community site contact.- Fetch cadence: one immediate fetch at adapter startup, then every 3 600 s. Reactive re-fetch (5 min cooldown) on any 5xx from the camera cloud API.
- Fallback chain: primary RSS (Wartungsarbeiten → Statusmeldungen) → HTML board page.
- Berlin TZ (MEZ/MESZ, DST-aware) parsed from German DD.MM.YYYY HH:MM–HH:MM text.
- +39 unit tests covering RSS parser, Atom format, MEZ/MESZ DST, fallback chain, camera-relevance filter, all state classifier branches. 481 tests total.
0.6.2 (2026-05-18)
FCM push channel now self-heals after transient socket drops.
- FCM auto-reconnect with exponential backoff (5 s → 30 s → 120 s → 600 s cap). A successful retry restores
info.fcm_activetohealthywithin seconds and resets the backoff so the next disconnect starts from 5 s again. The pending reconnect timer is cancelled on unload so the adapter never tries to start a half-torn-down listener during shutdown. - +6 unit tests covering the backoff progression, success/reset path, re-entrancy guard against rapid-fire disconnect events, and onUnload cleanup. 442 tests total.
0.6.1 (2026-05-18)
Cleanup: removed legacy iOS FCM code paths.
FCM_IOS_APP_IDconstant removed — the adapter has used only the Android Firebase key since its first release; the constant was dead code.mode: "ios"dispatch chain removed —FcmListenerOptions.mode,FcmCredentials.mode, andFcmRawCredentials.modenow accept"android" | "auto"only._registerWithCbs()always postsdeviceType: "ANDROID"— the"IOS"branch is gone.- Legacy-creds back-compat: users who stored credentials with
mode: "ios"from a hypothetical pre-cleanup install will have their persisted mode rewritten to"android"on first start — no re-registration triggered.
0.6.0 (2026-05-16)
Security hardening + reliability round.
- OAuth tokens + PKCE secrets are AES-encrypted at rest via the ioBroker system secret. Migration is automatic on first start.
- FCM credentials persisted across restarts (
info.fcm_creds, encrypted). Previously every adapter start triggered a full re-registration. - Camera-state poll runs per-camera in parallel (
Promise.all). With 4 cameras the per-tick wall-clock drops from ~N × 250 ms to ~250 ms. - Timer hygiene:
motion_activeauto-clear (90 s) and snapshot-idle teardown (60 s) now use adapter-core'sthis.setTimeout/this.clearTimeout, so adapter unload cancels them reliably. - Snapshot-saved log line is now
debug(wasinfo) — it was firing on every motion event and flooding logs on busy installations. - +51 unit tests covering the new encryption paths, FCM credential persistence, livestream toggle teardown, event processing dedup, siren / wallwasher handlers, idle teardown window, and reachability tracker. 436 tests total, 0 failing.
0.5.5 (2026-05-16)
Two forum-driven bugfixes reported against v0.5.4.
motion_activenow flips on the FCM-polling-fallback path (info.fcm_active="polling"). The shared post-event helper (_onMotionFired()) was only being called by the real FCM event handler and the synthetic motion trigger — not byfetchAndProcessEvents(). Affected users sawlast_motion_atupdate correctly whilemotion_activestayed permanentlyfalse.- Light state now syncs back from the Bosch app. The 30 s state poll now derives
front_light_enabledfromfrontLightSettings.brightness > 0andwallwasher_enabledfrommax(topLed, bottomLed) brightness > 0, so app toggles propagate within ~30 s.
0.5.4 (2026-05-15)
Login UX overhaul plus three small quality fixes.
- One-click Bosch login button in the instance settings. The browser-OAuth URL is also published as the
info.login_urldatapoint and rendered as a clickable link in the Admin UI. - No more terminate/restart loop while waiting for login. If a stale
redirect_urlor an expired PKCE pair causes the code exchange to fail, the adapter now clears the stale state, regenerates a fresh login URL, setsinfo.connection_status=auth_error, and stays alive in awaiting-login mode. - Reset-login button: new
Reset login (clear tokens & restart)button in the instance settings. info.connection_statustext state (logged_out|awaiting_login|connected|auth_error).info.last_login_atISO timestamp of the most recent successful token mint.- Privacy mode no longer flips
online=false: an indoor camera in permanent privacy mode used to drift offline after a few startup-snapshot retries. last_motion_atis now valid ISO 8601: strips the trailing[zone-id]from Bosch'sZonedDateTime#toStringformat so Blockly scripts and VIS widgets can parse the field with standard tooling.
0.5.3 (2026-05-14)
Five forum-driven improvements focused on the BlueIris / NVR-recorder integration.
- RTSP-aware proxy with transparent Digest auth: the TLS proxy now speaks RTSP and handles the Bosch Digest auth dance itself. Clients (BlueIris, iobroker.cameras, Frigate) connect to a clean
rtsp://host:port/rtsp_tunnel?inst=1&…URL — no credentials in the URL anymore. - Snapshot session keep-alive (60 s idle window): rapid
snapshot_triggerbursts reuse the warm Bosch session instead of payingPUT /v11/.../connectionon every snap. cameras.<id>.motion_active(new, boolean, read-only): edge-trigger DP, flipstrueon every motion / person / audio event, auto-clears tofalseafter 90 s.cameras.<id>.last_event_image+ Auto-snapshot on motion: every FCM motion / person / audio_alarm event now fetches a fresh JPEG and writes it as adata:image/jpeg;base64,…string.cameras.<id>.stream_url_sub(new, experimental): sub-stream URL viainst=2alongside the maininst=1stream_url.
0.5.2 (2026-05-14)
Per-camera livestream switch — default OFF.
cameras.<id>.livestream_enabled(new, boolean, writable, defaultfalse): explicit on/off switch for the continuous RTSP livestream. Streaming is now opt-in.- Snapshots remain unaffected: every
snapshot_triggerstill opens a session, fetches the JPEG, and then — whenlivestream_enabledisfalse— closes the session right after.
0.5.1 (2026-05-14)
Gen2 siren + RGB wallwasher colour, plus v0.5.0 forum-driven fixes.
- Siren (Gen2 only): new
cameras.<id>.siren_activeboolean DP. Writetrueto trigger the integrated 75 dB siren (panic alarm),falseto silence. - RGB wallwasher (Gen2 outdoor): two new DPs —
cameras.<id>.wallwasher_color(HEX#RRGGBB, empty string = warm white mode) andcameras.<id>.wallwasher_brightness(0…100). - Privacy state now syncs back from the Bosch app every 30 s.
stream_urlnow embeds Digest credentials and Bosch query params so external recorders no longer get "401 Unauthorized" on connect.- TLS-proxy port is sticky across session renewals and adapter restarts (persisted in
cameras.<id>._proxy_port). - New admin tab "RTSP / Stream": tickbox to bind the proxy to
0.0.0.0plus an external-host field so the published URL uses the ioBroker host's LAN IP.
0.4.0 (2026-05-13)
- Light-datapoint split:
front_light_enabled+wallwasher_enabledcan now be controlled independently - Synthetic motion trigger: write
truetocameras.<id>.motion_trigger(select event type viamotion_trigger_event_type) to inject a motion/person/audio_alarm event from an external sensor - RTSP session watchdog: LOCAL Bosch sessions renew automatically ~60 s before
maxSessionDurationexpires - Cloud-relay media paths fully removed: adapter enforces LOCAL-only for all media (RTSP + snapshots)
Older releases (0.0.1 – 0.3.3) are archived in CHANGELOG_OLD.md.
License
MIT License — see LICENSE.
Copyright (c) 2026 mosandlt