Онвиф

Адаптер для онвиф камер

Текущий релиз
1.1.9
Разработчик
TA2k, iobroker-community-adapters
Лицензия
MIT

ONVIF-адаптер для ioBroker

Адаптер для ONVIF-камер

Этот адаптер использует библиотеки Sentry для автоматического сообщения разработчикам об исключениях и ошибках в коде. Более подробную информацию, а также инструкции по отключению отправки сообщений об ошибках см. в документации Sentry-Plugin ! Система отчетности Sentry используется начиная с js-controller 3.0.

zur deutschen Dokumentation

Добавить камеры

Открытие:

При каждом запуске адаптера выполняется поиск с использованием имени пользователя и пароля, введенных в настройках, и предпринимается попытка входа в камеру. Если камера еще не добавлена в раздел «Объекты».

Обнаружение можно выполнить вручную в настройках. Если у камер разные учетные данные, вам нужно будет ввести их и выполнить обнаружение. В журнале вы увидите подробности процесса.

Для того чтобы камера снова была обнаружена, её достаточно просто удалить в разделе «Объекты».

Ручной поиск

Если функция обнаружения не работает, поиск камер можно выполнить вручную. Для этого необходимо ввести диапазон IP-адресов и портов и выполнить поиск вручную. В журнале можно увидеть подробности процесса.

Штаты

onvif.0.IP_PORT.events События камеры, например, обнаружение движения. Иногда для просмотра события необходимо его инициировать.

onvif.0.IP_PORT.general Общая информация о камерах

Информация о камере в файле onvif.0.IP_PORT.infos обновляется только при запуске адаптера или при выполнении команды remote.refresh.

URL видео и снимков экрана:

onvif.0.IP_PORT.infos.streamUris.MediaProfile_Channel1_MainStream.snapshotUrl.uri

onvif.0.IP_PORT.remote Управление камерой

onvif.0.IP_PORT.remote.refresh Обновление информационных данных

onvif.0.IP_PORT.remote.gotoHomePosition Установить PTZ-камеру в исходное положение

onvif.0.IP_PORT.remote.gotoPreset Выберите номер предустановки PTZ-камеры

onvif.0.IP_PORT.remote.snapshot Сохранить снимок в onvif.0.IP_PORT.snapshot

Сообщение

Адаптер получает сообщение "снимок" и возвращает изображение.

sendTo('onvif.0', 'snapshot', '192_168_178_100_80', (result) => {
  if (result) {
    sendTo('telegram.0', {
      text: result,

      type: 'photo',

      caption: 'camera2',
    });
  }
});

Сообщение, отправленное через Telegram

on('onvif.0.192_168_178_100_80.events.RuleEngine/CellMotionDetector/Motion', (obj) => {
  if (obj.state.val === true) {
    sendTo('onvif.0', 'snapshot', '192_168_178_100_80', (result) => {
      if (result) {
        sendTo('telegram.0', {
          text: result,

          type: 'photo',

          caption: 'Camera 2',
        });
      }
    });
  }
});

Включить поток в визуализацию

Если потоковое изображение должно отображаться в Apple HomeKit, создайте камеру непосредственно в Yahka. Если это не сработает или требуется HKSV, установите Scrypted в Docker и добавьте камеру с ONVIF и плагином HomeKit.

go2rtsp Docker

Поток обычно передается через RTSP. Преобразование через MotionEye очень ресурсоемко и сопровождается задержкой. Преобразование в WebRTC происходит быстрее и экономит ресурсы. Я рекомендую использовать go2rtsp . Для этого необходимо создать Docker-образ из alexxit/go2rtc. https://hub.docker.com/r/alexxit/go2rtc

 image: alexxit/go2rtc
    network_mode: host # important for WebRTC, HomeKit, UDP cameras
    privileged: true # only for FFmpeg hardware transcoding
    restart: unless-stopped # autorestart on fail or config change from WebUI
    environment:
      - TZ=Europe/Berlin # timezone in logs
    volumes:
      - "~/go2rtc:/config" # folder for go2rtc.yaml file (edit from WebUI)

Необходимо указать в качестве пути /config том, а в качестве хоста — сеть.

Затем доступ к go2rtsp осуществляется через

http://IP:1984

Затем вы можете добавить поток. URL-адрес потока можно найти, например, в разделеonvif.0.IP_PORT.infos.streamUris.ProfileName.live_stream_tcp.uri

Вставить поток как iFrame

ДобавитьiFrame Вставьте виджет в Vis и используйте ссылку на поток от go2rtsp в качестве источника.

http://192.168.178.1:1984/stream.html?src=camera&mode=webrtc

Rtsp2Web Docker

Альтернативным вариантом является Docker-контейнер RTSPtoWeb . Однако его настройка сложнее. Docker-контейнер необходимо создать по адресу ghcr.io/deepch/rtsptoweb:latest.

docker run --name rtsp-to-web -v /YOURPATHFORCONFIG:/config --network host ghcr.io/deepch/rtsptoweb:latest

Необходимо указать том для пути /config, а сеть должна быть настроена как хост.

Затем доступ к rtsptoweb можно получить через

http://IP:8083

Затем вы можете добавить поток. URL-адрес потока можно найти, например, в разделеonvif.0.IP_PORT.infos.streamUris.ProfileName.live_stream_tcp.uri

Затем нам понадобится идентификатор потока. Для этого отредактируйте поток и скопируйте идентификатор из URL-адреса.

http://192.168.178.2:8083/pages/stream/edit/ddbdb583-9f80-4b61-bafa-613aa7a5daa5

Вставьте отдельный поток в визуализацию.

Затем выберите HTML-объект в виджете. После этого в поле HTML введите адрес rtsp2web-сервера с идентификатором потока:

Если необходимо добавить несколько потоков,webrtc-url иwebrtc-video В HTML и скрипте необходимо заменить новым идентификатором, например:webrtc-url2 иwebrtc-video2

<input
  type="hidden"
  name="webrtc-url"
  id="webrtc-url"
  value="http://192.168.0.2:8083/stream/ddbdb583-9f80-4b61-bafa-613aa7a5daa5/channel/0/webrtc"
/>

<video id="webrtc-video" autoplay muted playsinline controls style="max-width: 100%; max-height: 100%;"></video>

Добавьте этот скрипт в виджет в разделе «Скрипты»:

setTimeout(function () {
  function startPlay(videoEl, url) {
    const webrtc = new RTCPeerConnection({
      iceServers: [
        {
          urls: ['stun:stun.l.google.com:19302'],
        },
      ],
      sdpSemantics: 'unified-plan',
    });
    webrtc.ontrack = function (event) {
      console.log(event.streams.length + ' track is delivered');
      videoEl.srcObject = event.streams[0];
      videoEl.play();
    };
    webrtc.addTransceiver('video', { direction: 'sendrecv' });
    webrtc.onnegotiationneeded = async function handleNegotiationNeeded() {
      const offer = await webrtc.createOffer();

      await webrtc.setLocalDescription(offer);

      fetch(url, {
        method: 'POST',
        body: new URLSearchParams({ data: btoa(webrtc.localDescription.sdp) }),
      })
        .then((response) => response.text())
        .then((data) => {
          try {
            webrtc.setRemoteDescription(new RTCSessionDescription({ type: 'answer', sdp: atob(data) }));
          } catch (e) {
            console.warn(e);
          }
        });
    };

    const webrtcSendChannel = webrtc.createDataChannel('rtsptowebSendChannel');
    webrtcSendChannel.onopen = (event) => {
      console.log(`${webrtcSendChannel.label} has opened`);
      webrtcSendChannel.send('ping');
    };
    webrtcSendChannel.onclose = (_event) => {
      console.log(`${webrtcSendChannel.label} has closed`);
      startPlay(videoEl, url);
    };
    webrtcSendChannel.onmessage = (event) => console.log(event.data);
  }

  const videoEl = document.querySelector('#webrtc-video');
  const webrtcUrl = document.querySelector('#webrtc-url').value;

  startPlay(videoEl, webrtcUrl);
}, 1000);

Все потоки отображаются в виде iFrame.

В качестве альтернативы вы также можете вставить обзор камеры в виде iframe: Добавить виджетiFrame и введите сервер rtsp2web в качестве источника:

http://192.168.0.2:8083/pages/multiview/full?controls

поддержка FFMpeg

Если камера не поддерживает создание снимков, ffmpeg создаст снимок из потока RTSP.

Включите сервер моментальных снимков в визуальные данные.

Адаптер предоставляет сервер для создания моментальных снимков без пароля. Активируйте сервер в настройках экземпляра, и вы сможете получить текущий моментальный снимок по адресу http://iobrokerIp:8095/CAMERAIP_PORT, например, http://192.168.0.1:8095/192_168_0_1_80 .

Вставьте виджет изображения в визуализацию, укажите URL-адрес в качестве источника и выберите время обновления.

Включить снимок в визуализацию

По возможности используйте snapshotUri, например.

onvif.0.IP_PORT.infos.streamUris.MediaProfile_Channel1_MainStream.snapshotUrl.uri

Не используйте состояние в качестве потока, иначе нагрузка на диск будет слишком высокой.

Обновите состояние через onvif.0.IP_PORT.remote.snapshot

НазначитьString img src элемент в состояние onvif.0.IP_PORT.snapshot.

Или в качестве альтернативы, еслиString img src не работает

Вставьте состояние onvif.0.IP_PORT.snapshot следующим образом:HTML вставьте элемент в визуальный элемент со следующим содержимым

<img src="/ru/adapterref/iobroker.onvif/{onvif.0.IP_PORT.snapshot}" width="500px" />

Создать новый снимок по событию:

on('onvif.0.192_168_178_100_80.events.RuleEngine/CellMotionDetector/Motion', (obj) => {
  if (obj.state.val === true) {
    setState('onvif.0.192_168_178_100_80.remote.snapshot', true, false);
  }
});

Дискуссия (на немецком языке)

https://forum.iobroker.net/topic/63145/test-adapter-onvif-camera-v1-0-0

Changelog

1.1.8 (2026-08-21)

  • (TA2k) Fixed reconnect loop: the watchdog now only rebuilds on non-retryable event errors, so cameras that periodically reset the event socket ("socket hang up") are left to the onvif library's own retry instead of reconnecting every 30s
  • (TA2k) Retryable event errors are logged at debug instead of warn and no longer flip the connection state
  • (TA2k) Updated onvif to 0.8.2 and dev dependencies

1.1.7 (2026-08-20)

  • (mcm1957) clean release built to fix missing tagging and github release

1.1.6 (2026-08-08)

  • (TA2k) Faster reconnect after a camera reboot (detection in ~30-50s instead of ~4min)
  • (TA2k) Connection state now reflects the real reconnect instead of flipping back to true too early
  • (TA2k) Throttled the repeated event error log messages during a reboot

1.1.5 (2026-08-06)

  • (copilot) Adapter requires node.js >= 22 now
  • (copilot) Adapter requires admin >= 7.7.22 now
  • (copilot) Adapter requires js-controller >= 6.0.11 now

1.1.4 (2024-05-27)

  • update onvif lib to support newer TAPO cameras
  • (mcm1957) Adapter requires nodejs >=18 now.

1.1.3 (2024-03-15)

  • Allow non number PTZ presets

License

MIT License

Copyright (c) 2026 iobroker-community-adapters iobroker-community-adapters@gmx.de
Copyright (c) 2023-2024 TA2k tombox2020@gmail.com

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

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

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