iobroker.motioneye 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -8
- package/admin/i18n/de.json +22 -0
- package/admin/i18n/en.json +22 -0
- package/admin/i18n/es.json +22 -0
- package/admin/i18n/fr.json +22 -0
- package/admin/i18n/it.json +22 -0
- package/admin/i18n/nl.json +22 -0
- package/admin/i18n/pl.json +22 -0
- package/admin/i18n/pt.json +22 -0
- package/admin/i18n/ru.json +22 -0
- package/admin/i18n/uk.json +22 -0
- package/admin/i18n/zh-cn.json +22 -0
- package/admin/jsonConfig.json +195 -4
- package/io-package.json +34 -1
- package/lib/cameraDiscovery.js +130 -0
- package/lib/cameraDiscovery.test.js +76 -0
- package/lib/cameraRegistry.js +3 -0
- package/lib/mediaStorage.js +62 -0
- package/lib/mediaStorage.test.js +31 -0
- package/lib/motionEyeApi.js +5 -3
- package/lib/streamManager.js +6 -9
- package/main.js +99 -3
- package/package.json +3 -3
package/admin/i18n/ru.json
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
"camera_id": "Внутренний идентификатор",
|
|
6
6
|
"camera_id_help": "Стабильный ключ для вебхуков (например, auffahrt). Оставьте пустым, чтобы получить производное от имени.",
|
|
7
7
|
"camera_id_placeholder": "авто от имени",
|
|
8
|
+
"camera_mediaFolder": "Медиа-папка",
|
|
9
|
+
"camera_mediaFolder_help": "Имя папки в /var/lib/motioneye (например, Bambu). Применяется при запуске адаптера, когда включена синхронизация конфигурации MotionEye. Оставьте пустым, чтобы сохранить значение MotionEye по умолчанию (Camera<ID>). Не переименовывает существующие папки на диске.",
|
|
10
|
+
"camera_mediaFolder_placeholder": "необязательный",
|
|
8
11
|
"camera_motionEyeId": "Идентификатор MotionEye",
|
|
9
12
|
"camera_motionEyeId_help": "Числовой идентификатор камеры из MotionEye (/config/list)",
|
|
10
13
|
"camera_name": "Отображаемое имя",
|
|
@@ -18,6 +21,24 @@
|
|
|
18
21
|
"header_stream": "Параметры потока",
|
|
19
22
|
"header_timing": "Опрос и тайм-ауты",
|
|
20
23
|
"header_webhook": "Вебхук",
|
|
24
|
+
"help_cameras": "На вкладке <b>Камеры</b> используйте <b>Загрузить камеры из MotionEye</b>, чтобы получить список камер из MotionEye и добавить недостающие строки в таблицу (существующие записи сохраняются). Для этой кнопки экземпляр адаптера должен быть <b>работающим</b>.<br><br><b>Идентификатор MotionEye:</b> В веб-интерфейсе MotionEye откройте камеру → <b>Видеоустройство</b> → поле <b>Идентификатор камеры</b>. Или запросите <code>/config/list</code> через порт 8765.<br><br><b>Отображаемое имя:</b> имя канала ioBroker — может отличаться от метки MotionEye.<br><b>Внутренний идентификатор:</b> Стабильный ключ веб-перехватчика (например, <code>auffahrt</code>). Оставьте пустым, чтобы получить имя из отображаемого имени.<br><b>Папка Media:</b> Необязательное имя папки в <code>/var/lib/motioneye</code>. Применяется при запуске адаптера, когда включена синхронизация конфигурации.",
|
|
25
|
+
"help_connection": "<b>Хост MotionEye</b> — IP-адрес или имя хоста вашего сервера MotionEye.<br><b>Порт API конфигурации MotionEye</b> — по умолчанию <code>8765</code> (режим, веб-перехватчики, поток).<br><b>Порт HTTP Motion</b> — по умолчанию <code>7999</code> (снимки).<br><b>Управление MotionEye через API конфигурации</b> — выйти <b>включено</b> для обычного использования. Адаптер записывает режим, URL-адреса веб-перехватчиков и включение/выключение потоковой передачи в MotionEye; ioBroker контролирует обнаружение и прямые трансляции.<br><br><b>Хост веб-перехватчика</b> — IP-адрес вашего хоста ioBroker, доступный <i>из MotionEye</i> (например, <code>192.168.130.130</code>). Требуется для URL-адресов веб-перехватчиков.<br><b>Порт веб-перехватчика</b> — по умолчанию <code>8090</code>; разрешить входящий трафик на хосте ioBroker.",
|
|
26
|
+
"help_intro": "<b>Адаптер MotionEye</b> подключает камеры MotionEye к ioBroker: обнаружение движения с помощью веб-перехватчиков, снимков, прямых трансляций и управления режимами (<code>выкл.</code> / <code> Still</code> / <code>sharp</code>).<br><br>Информация отображается в <code>motioneye.<instance>.0_info</code> (подключение, версии, камеры онлайн).",
|
|
27
|
+
"help_modes": "<table style=\"width:100%;border-collapse:collapse;font-size:0.875rem\"><thead><tr style=\"border-bottom:1px Solid #546e7a\"><th style=\"text-align:left;padding:8px 6px;width:18%\">Режим</th><th style=\"text-align:left;padding:8px\" 6px\">Описание</th></tr></thead><tbody><tr style=\"border-bottom:1px Solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>off</code></td><td style=\"padding:6px\">Обнаружение движения выключен</td></tr><tr style=\"border-bottom:1px Solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code> Still</code></td><td style=\"padding:6px\">Только триггер движения — без записи видео</td></tr><tr><td style=\"padding:6px\"><code>sharp</code></td><td style=\"padding:6px\">Обнаружение движения + видео запись</td></tr></tbody></table>",
|
|
28
|
+
"help_readme": "Полная документация:<br><br>• <a href=\"https://github.com/inventwo/ioBroker.motioneye/blob/main/README.md\">README адаптера на GitHub</a>",
|
|
29
|
+
"help_section_cameras": "Камеры",
|
|
30
|
+
"help_section_connection": "Подключение и вебхуки",
|
|
31
|
+
"help_section_modes": "Режимы камеры",
|
|
32
|
+
"help_section_setup": "Быстрый старт",
|
|
33
|
+
"help_section_states": "Точек данных на камеру",
|
|
34
|
+
"help_section_stream": "Прямая трансляция и HTML-виджеты",
|
|
35
|
+
"help_setup": "1. Задайте <b>хост MotionEye</b>, учетные данные и <b>хост веб-перехватчика</b> на вкладке «Настройки».<br>2. На вкладке «Камеры» нажмите <b>Загрузить камеры из MotionEye</b> (экземпляр должен быть запущен) или добавьте строки вручную.<br>3. Настройте отображаемые имена и дополнительные папки мультимедиа.<br>4. <b>Сохраните</b> конфигурацию экземпляра и <b>перезапустите</b> адаптер — точки данных будут созданы, а URL-адреса веб-перехватчиков запишутся в MotionEye.",
|
|
36
|
+
"help_states": "<table style=\"width:100%;border-collapse:collapse;font-size:0.875rem\"><thead><tr style=\"border-bottom:1px Solid #546e7a\"><th style=\"text-align:left;padding:8px 6px;width:16%\">Состояние</th><th style=\"text-align:left;padding:8px\" 6px;width:10%\">Чтение</th><th style=\"text-align:left;padding:8px 6px;width:10%\">Запись</th><th style=\"text-align:left;padding:8px 6px\">Описание</th></tr></thead><tbody><tr style=\"border-bottom:1px Solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>mode</code></td><td style=\"padding:6px\">да</td><td style=\"padding:6px\">да</td><td style=\"padding:6px\">Режим камеры: выключено, неподвижно, резкость</td></tr><tr style=\"border-bottom:1px Solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>движение</code></td><td style=\"padding:6px\">да</td><td style=\"padding:6px\">нет</td><td style=\"padding:6px\">Обнаружено движение (webhook, автоматический сброс)</td></tr><tr style=\"border-bottom:1px\" Solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>статус</code></td><td style=\"padding:6px\">да</td><td style=\"padding:6px\">нет</td><td style=\"padding:6px\">Последняя синхронизация/текст ошибки</td></tr><tr style=\"border-bottom:1px Solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>снимок</code></td><td style=\"padding:6px\">нет</td><td style=\"padding:6px\">да</td><td style=\"padding:6px\">Запустить снимок (кнопка)</td></tr><tr style=\"border-bottom:1px Solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>поток</code></td><td style=\"padding:6px\">да</td><td style=\"padding:6px\">да</td><td style=\"padding:6px\">Прямой видеопоток вкл./выкл.</td></tr><tr style=\"border-bottom:1px Solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>streamPulse</code></td><td style=\"padding:6px\">нет</td><td style=\"padding:6px\">да</td><td style=\"padding:6px\">Короткий импульс потока (кнопка)</td></tr><tr style=\"border-bottom:1px Solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>streamUrl</code></td><td style=\"padding:6px\">да</td><td style=\"padding:6px\">нет</td><td style=\"padding:6px\">Готовый HTML для любого HTML-виджета</td></tr><tr><td style=\"padding:6px\"><code>webhookUrl</code></td><td style=\"padding:6px\">да</td><td style=\"padding:6px\">нет</td><td style=\"padding:6px\">Настроенный URL-адрес веб-перехватчика (только для чтения)</td></tr></tbody></table>",
|
|
37
|
+
"help_stream": "Установите для <code>stream</code> значение <code>true</code> для живого потока MJPEG. Используйте <code>streamPulse</code> для предварительного просмотра по времени (см. <b>Автоотключение Stream Pulse</b> в настройках).<br><br>Состояние <code>streamUrl</code> предоставляет готовый к использованию HTML (например, тег <code><img></code>) для любого виджета с поддержкой HTML в VIS, VIS2 или на информационных панелях. Он обновляется автоматически при включении или выключении потока.",
|
|
38
|
+
"load_cameras_button": "Загрузка камер из MotionEye",
|
|
39
|
+
"load_cameras_help": "Получает /config/list из MotionEye и добавляет камеры, которых еще нет в таблице. Экземпляр адаптера должен быть запущен. Сохраните конфигурацию и перезапустите после добавления камер.",
|
|
40
|
+
"load_cameras_result_added": "В таблицу добавлены новые камеры. Сохраните конфигурацию и перезапустите экземпляр адаптера.",
|
|
41
|
+
"load_cameras_result_none": "Новых камер нет — все камеры MotionEye уже есть в таблице.",
|
|
21
42
|
"mode_off": "Выкл. — нет обнаружения",
|
|
22
43
|
"mode_sharp": "Sharp — движение + запись видео",
|
|
23
44
|
"mode_still": "Неподвижно — только триггер движения",
|
|
@@ -37,6 +58,7 @@
|
|
|
37
58
|
"streamAutoOffMs": "Автоматическое отключение импульса потока (мс)",
|
|
38
59
|
"streamAutoOffMs_help": "Используется только дляstreamPulse — поток отключается по истечении этого времени (0 = никогда)",
|
|
39
60
|
"tab_cameras": "Камеры",
|
|
61
|
+
"tab_help": "Помощь",
|
|
40
62
|
"tab_settings": "Настройки",
|
|
41
63
|
"useMotionEyeConfig": "Управление MotionEye через API конфигурации",
|
|
42
64
|
"useMotionEyeConfig_help": "Оставьте включённым для обычной работы. Адаптер записывает режим камеры, URL вебхуков и поток вкл./выкл. в MotionEye (порт 8765). ioBroker управляет обнаружением движения и потоками; веб-интерфейс MotionEye обновляется как побочный эффект. Отключайте только при полностью ручной настройке MotionEye.",
|
package/admin/i18n/uk.json
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
"camera_id": "Внутрішній ID",
|
|
6
6
|
"camera_id_help": "Стабільний ключ для веб-хуків (наприклад, auffahrt). Залиште порожнім, щоб отримати назву.",
|
|
7
7
|
"camera_id_placeholder": "авто від імені",
|
|
8
|
+
"camera_mediaFolder": "Медіа папка",
|
|
9
|
+
"camera_mediaFolder_help": "Назва папки в /var/lib/motioneye (наприклад, Bambu). Застосовується під час запуску адаптера, коли ввімкнено синхронізацію конфігурації MotionEye. Залиште поле порожнім, щоб зберегти MotionEye за замовчуванням (Camera<ID>). Не перейменовує існуючі папки на диску.",
|
|
10
|
+
"camera_mediaFolder_placeholder": "необов'язковий",
|
|
8
11
|
"camera_motionEyeId": "MotionEye ID",
|
|
9
12
|
"camera_motionEyeId_help": "Числовий ідентифікатор камери з MotionEye (/config/list)",
|
|
10
13
|
"camera_name": "Відображуване ім'я",
|
|
@@ -18,6 +21,24 @@
|
|
|
18
21
|
"header_stream": "Параметри потоку",
|
|
19
22
|
"header_timing": "Опитування та тайм-аути",
|
|
20
23
|
"header_webhook": "Вебхук",
|
|
24
|
+
"help_cameras": "На вкладці <b>Камери</b> скористайтеся кнопкою <b>Завантажити камери з MotionEye</b>, щоб отримати список камер із MotionEye і додати відсутні рядки до таблиці (існуючі записи зберігаються). Для цієї кнопки екземпляр адаптера має бути <b>запущений</b>.<br><br><b>Ідентифікатор MotionEye:</b> у веб-інтерфейсі MotionEye відкрийте камеру → <b>Відеопристрій</b> → поле <b>Ідентифікатор камери</b>. Або надішліть запит <code>/config/list</code> на порт 8765.<br><br><b>Відображувана назва:</b> назва каналу ioBroker — може відрізнятися від мітки MotionEye.<br><b>Внутрішній ідентифікатор:</b> стабільний ключ вебхука (наприклад, <code>auffahrt</code>). Залиште пустим, щоб отримати відображуване ім’я.<br><b>Папка медіа:</b> Додаткова назва папки в <code>/var/lib/motioneye</code>. Застосовується під час запуску адаптера, коли ввімкнено синхронізацію конфігурації.",
|
|
25
|
+
"help_connection": "<b>Хост MotionEye</b> — IP-адреса або ім’я хосту вашого сервера MotionEye.<br><b>Порт API конфігурації MotionEye</b> — за умовчанням <code>8765</code> (режим, веб-хуки, потік).<br><b>Порт HTTP Motion</b> — за замовчуванням <code>7999</code> (миттєві знімки).<br><b>Керуйте MotionEye через API конфігурації</b> — вийдіть <b>увімкнено</b> для звичайного використання. Адаптер записує режим, URL-адреси webhook і вмикає/вимикає потік у MotionEye; ioBroker контролює виявлення та прямі трансляції.<br><br><b>Хост Webhook</b> — IP-адреса вашого хосту ioBroker доступна <i>з MotionEye</i> (наприклад, <code>192.168.130.130</code>). Необхідно для URL-адрес webhook.<br><b>Порт webhook</b> — за умовчанням <code>8090</code>; дозволити вхідний трафік на хост ioBroker.",
|
|
26
|
+
"help_intro": "<b>Адаптер MotionEye</b> підключає камери MotionEye до ioBroker: виявлення руху через веб-перехоплення, знімки, прямі трансляції та керування режимами (<code>off</code> / <code>still</code> / <code>sharp</code>).<br><br>Інформаційні стани живуть у <code>motioneye.<instance>.0_info</code> (підключення, версії, камери) онлайн).",
|
|
27
|
+
"help_modes": "<table style=\"width:100%;border-collapse:collapse;font-size:0.875rem\"><thead><tr style=\"border-bottom:1px solid #546e7a\"><th style=\"text-align:left;padding:8px 6px;width:18%\">Режим</th><th style=\"text-align:left;padding:8px 6px\">Опис</th></tr></thead><tbody><tr style=\"border-bottom:1px solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>off</code></td><td style=\"padding:6px\">Виявлення руху вимкнено</td></tr><tr style=\"border-bottom:1px solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>still</code></td><td style=\"padding:6px\">Лише тригер руху — без запису відео</td></tr><tr><td style=\"padding:6px\"><code>sharp</code></td><td style=\"padding:6px\">Виявлення руху + відео запис</td></tr></tbody></table>",
|
|
28
|
+
"help_readme": "Повна документація:<br><br>• <a href=\"https://github.com/inventwo/ioBroker.motioneye/blob/main/README.md\">Adapter README на GitHub</a>",
|
|
29
|
+
"help_section_cameras": "Фотоапарати",
|
|
30
|
+
"help_section_connection": "Підключення та веб-хуки",
|
|
31
|
+
"help_section_modes": "Режими камери",
|
|
32
|
+
"help_section_setup": "Швидкий старт",
|
|
33
|
+
"help_section_states": "Точки даних на камеру",
|
|
34
|
+
"help_section_stream": "Пряма трансляція та HTML-віджети",
|
|
35
|
+
"help_setup": "1. Установіть <b>хост MotionEye</b>, облікові дані та <b>хост вебхуку</b> на вкладці «Налаштування».<br>2. На вкладці «Камери» натисніть <b>Завантажити камери з MotionEye</b> (примірник має бути запущений) або додайте рядки вручну.<br>3. Налаштуйте відображувані назви та додаткові медіа-папки.<br>4. <b>Збережіть</b> конфігурацію екземпляра та <b>перезапустіть</b> адаптер — точки даних будуть створені, а URL-адреси веб-хуку записані в MotionEye.",
|
|
36
|
+
"help_states": "<table style=\"width:100%;border-collapse:collapse;font-size:0.875rem\"><thead><tr style=\"border-bottom:1px solid #546e7a\"><th style=\"text-align:left;padding:8px 6px;width:16%\">Стан</th><th style=\"text-align:left;padding:8px 6px;width:10%\">Прочитати</th><th style=\"text-align:left;padding:8px 6px;width:10%\">Написати</th><th style=\"text-align:left;padding:8px 6px\">Опис</th></tr></thead><tbody><tr style=\"border-bottom:1px solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>режим</code></td><td style=\"padding:6px\">так</td><td style=\"padding:6px\">так</td><td style=\"padding:6px\">Режим камери: вимкнено, нерухомо, різко</td></tr><tr style=\"border-bottom:1px solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>motion</code></td><td style=\"padding:6px\">yes</td><td style=\"padding:6px\">ні</td><td style=\"padding:6px\">Виявлено рух (вебхук, автоматичне скидання)</td></tr><tr style=\"border-bottom:1px solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>статус</code></td><td style=\"padding:6px\">так</td><td style=\"padding:6px\">ні</td><td style=\"padding:6px\">Остання синхронізація / текст помилки</td></tr><tr style=\"border-bottom:1px solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>миттєвий знімок</code></td><td style=\"padding:6px\">ні</td><td style=\"padding:6px\">так</td><td style=\"padding:6px\">Тригерний знімок (кнопка)</td></tr><tr style=\"border-bottom:1px solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>потік</code></td><td style=\"padding:6px\">так</td><td style=\"padding:6px\">так</td><td style=\"padding:6px\">живе відеопотік увімк./вимк.</td></tr><tr style=\"border-bottom:1px solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>streamPulse</code></td><td style=\"padding:6px\">ні</td><td style=\"padding:6px\">так</td><td style=\"padding:6px\">Короткий потік пульс (кнопка)</td></tr><tr style=\"border-bottom:1px solid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>streamUrl</code></td><td style=\"padding:6px\">так</td><td style=\"padding:6px\">ні</td><td style=\"padding:6px\">Готовий HTML для будь-якого HTML-віджета</td></tr><tr><td style=\"padding:6px\"><code>webhookUrl</code></td><td style=\"padding:6px\">yes</td><td style=\"padding:6px\">ні</td><td style=\"padding:6px\">Налаштована URL-адреса webhook (тільки для читання)</td></tr></tbody></table>",
|
|
37
|
+
"help_stream": "Установіть для <code>stream</code> значення <code>true</code> для прямого потоку MJPEG. Використовуйте <code>streamPulse</code> для тимчасового попереднього перегляду (див. <b>Автоматичне вимкнення пульсу потоку</b> в налаштуваннях).<br><br>Стан <code>streamUrl</code> надає готовий до використання HTML (наприклад, тег <code><img></code>) для будь-якого віджета з підтримкою HTML у VIS, VIS2 або на інформаційних панелях. Оновлюється автоматично, коли вмикається або вимикається потік.",
|
|
38
|
+
"load_cameras_button": "Завантажте камери з MotionEye",
|
|
39
|
+
"load_cameras_help": "Отримує /config/list з MotionEye і додає камери, яких ще немає в таблиці. Екземпляр адаптера повинен бути запущений. Збережіть конфігурацію та перезапустіть після додавання камер.",
|
|
40
|
+
"load_cameras_result_added": "У таблицю додано нові камери. Збережіть конфігурацію та перезапустіть екземпляр адаптера.",
|
|
41
|
+
"load_cameras_result_none": "Немає нових камер — усі камери MotionEye вже є в таблиці.",
|
|
21
42
|
"mode_off": "Вимкнуто — не виявлено",
|
|
22
43
|
"mode_sharp": "Sharp — рух + запис відео",
|
|
23
44
|
"mode_still": "Ще — тільки тригер руху",
|
|
@@ -37,6 +58,7 @@
|
|
|
37
58
|
"streamAutoOffMs": "Автоматичне відключення імпульсу потоку (мс)",
|
|
38
59
|
"streamAutoOffMs_help": "Використовується тільки streamPulse — потік вимикається через цей час (0 = ніколи)",
|
|
39
60
|
"tab_cameras": "Фотоапарати",
|
|
61
|
+
"tab_help": "Довідка",
|
|
40
62
|
"tab_settings": "Налаштування",
|
|
41
63
|
"useMotionEyeConfig": "Керувати MotionEye через API конфігурації",
|
|
42
64
|
"useMotionEyeConfig_help": "Залиште увімкненим для звичайної роботи. Адаптер записує режим камери, URL вебхуків і потік увімк./вимк. у MotionEye (порт 8765). ioBroker керує виявленням руху та потоками; веб-інтерфейс MotionEye оновлюється як побічний ефект. Вимикайте лише за повністю ручного налаштування MotionEye.",
|
package/admin/i18n/zh-cn.json
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
"camera_id": "内部ID",
|
|
6
6
|
"camera_id_help": "Webhooks 的稳定密钥(例如 auffahrt)。留空以从名称派生。",
|
|
7
7
|
"camera_id_placeholder": "从名称自动",
|
|
8
|
+
"camera_mediaFolder": "媒体文件夹",
|
|
9
|
+
"camera_mediaFolder_help": "/var/lib/motioneye 下的文件夹名称(例如 Bambu)。当启用 MotionEye 配置同步时应用于适配器启动。留空以保留 MotionEye 默认值 (Camera<ID>)。不重命名磁盘上的现有文件夹。",
|
|
10
|
+
"camera_mediaFolder_placeholder": "选修的",
|
|
8
11
|
"camera_motionEyeId": "运动眼ID",
|
|
9
12
|
"camera_motionEyeId_help": "来自 MotionEye 的数字摄像机 ID (/config/list)",
|
|
10
13
|
"camera_name": "显示名称",
|
|
@@ -18,6 +21,24 @@
|
|
|
18
21
|
"header_stream": "串流选项",
|
|
19
22
|
"header_timing": "轮询和超时",
|
|
20
23
|
"header_webhook": "网络钩子",
|
|
24
|
+
"help_cameras": "在<b>相机</b>选项卡上,使用<b>从 MotionEye 加载相机</b>从 MotionEye 获取相机列表并将缺失的行添加到表中(保留现有条目)。此按钮的适配器实例必须<b>正在运行</b>。<br><br><b>MotionEye ID:</b>在 MotionEye Web UI 中打开相机 → <b>视频设备</b> → 字段<b>相机 ID</b>。或者在端口 8765 上查询 <code>/config/list</code>。<br><br><b>显示名称:</b> ioBroker 通道名称 — 可以与 MotionEye 标签不同。<br><b>内部 ID:</b> 稳定的 webhook 密钥(例如 <code>auffahrt</code>)。留空以从显示名称派生。<br><b>媒体文件夹:</b><code>/var/lib/motioneye</code> 下的可选文件夹名称。当启用配置同步时应用于适配器启动。",
|
|
25
|
+
"help_connection": "<b>MotionEye 主机</b> - MotionEye 服务器的 IP 或主机名。<br><b>MotionEye 配置 API 端口</b> - 默认 <code>8765</code>(模式、webhooks、流)。<br><b>Motion HTTP 端口</b> - 默认 <code>7999</code>(快照)。<br><b>通过配置 API 控制 MotionEye</b> - 离开<b>已启用</b>以供正常使用。适配器将模式、Webhook URL 和流开/关写入 MotionEye; ioBroker 控制检测和实时流。<br><br><b>Webhook 主机</b> — <i>可从 MotionEye</i> 访问 ioBroker 主机的 IP(例如 <code>192.168.130.130</code>)。 Webhook URL 必需。<br><b>Webhook 端口</b> — 默认 <code>8090</code>;允许 ioBroker 主机上的入站流量。",
|
|
26
|
+
"help_intro": "<b>MotionEye 适配器</b>将 MotionEye 摄像头连接到 ioBroker:通过 Webhooks、快照、实时流和模式控制(<code>off</code> / <code>still</code> / <code>sharp</code>)进行运动检测。<br><br>信息状态在 <code>motioneye.<instance>.0_info</code> 下实时显示(连接、版本、在线摄像头)。",
|
|
27
|
+
"help_modes": "<table style=\"width:100%;border-collapse:collapse;font-size:0.875rem\"><thead><tr style=\"border-bottom:1pxsolid #546e7a\"><th style=\"text-align:left;padding:8px 6px;width:18%\">模式</th><th style=\"text-align:left;padding:8px 6px\">说明</th></tr></thead><tbody><tr style=\"border-bottom:1pxsolid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>关闭</code></td><td style=\"padding:6px\">运动检测关闭</td></tr><tr style=\"border-bottom:1pxsolid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>静止</code></td><td style=\"padding:6px\">仅运动触发 - 无视频录制</td></tr><tr><td style=\"padding:6px\"><code>锐利</code></td><td style=\"padding:6px\">运动检测+视频录音</td></tr></tbody></table>",
|
|
28
|
+
"help_readme": "完整文档:<br><br>• <a href=\"https://github.com/inventwo/ioBroker.motioneye/blob/main/README.md\">GitHub 上的适配器自述文件</a>",
|
|
29
|
+
"help_section_cameras": "相机",
|
|
30
|
+
"help_section_connection": "连接和网络钩子",
|
|
31
|
+
"help_section_modes": "相机模式",
|
|
32
|
+
"help_section_setup": "快速启动",
|
|
33
|
+
"help_section_states": "每个相机的数据点",
|
|
34
|
+
"help_section_stream": "直播和 HTML 小部件",
|
|
35
|
+
"help_setup": "1. 在“设置”选项卡上设置<b>MotionEye 主机</b>、凭据和<b>webhook 主机</b>。<br>2.在“相机”选项卡上,单击<b>从 MotionEye 加载相机</b>(实例必须正在运行)或手动添加行。<br>3.调整显示名称和可选媒体文件夹。<br>4。 <b>保存</b>实例配置并<b>重新启动</b>适配器 - 创建数据点并将 Webhook URL 写入 MotionEye。",
|
|
36
|
+
"help_states": "<table style=\"width:100%;border-collapse:collapse;font-size:0.875rem\"><thead><tr style=\"border-bottom:1pxsolid #546e7a\"><th style=\"text-align:left;padding:8px 6px;width:16%\">状态</th><th style=\"text-align:left;padding:8px 6px;width:10%\">读取</th><th style=\"text-align:left;padding:8px 6px;width:10%\">写入</th><th style=\"text-align:left;padding:8px 6px\">描述</th></tr></thead><tbody><tr style=\"border-bottom:1pxsolid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>模式</code></td><td style=\"padding:6px\">是</td><td style=\"padding:6px\">是</td><td style=\"padding:6px\">相机模式:关闭、静止、锐利</td></tr><tr style=\"border-bottom:1pxsolid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>motion</code></td><td style=\"padding:6px\">是</td><td style=\"padding:6px\">否</td><td style=\"padding:6px\">检测到运动(webhook,自动重置)</td></tr><tr style=\"border-bottom:1pxsolid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>状态</code></td><td style=\"padding:6px\">是</td><td style=\"padding:6px\">否</td><td style=\"padding:6px\">上次同步/错误文本</td></tr><tr style=\"border-bottom:1pxsolid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>快照</code></td><td style=\"padding:6px\">否</td><td style=\"padding:6px\">是</td><td style=\"padding:6px\">触发快照(按钮)</td></tr><tr style=\"border-bottom:1pxsolid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>流</code></td><td style=\"padding:6px\">是</td><td style=\"padding:6px\">是</td><td style=\"padding:6px\">实时视频流开/关</td></tr><tr style=\"border-bottom:1pxsolid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>streamPulse</code></td><td style=\"padding:6px\">否</td><td style=\"padding:6px\">是</td><td style=\"padding:6px\">短流脉冲(按钮)</td></tr><tr style=\"border-bottom:1pxsolid rgba(84,110,122,0.35)\"><td style=\"padding:6px\"><code>streamUrl</code></td><td style=\"padding:6px\">是</td><td style=\"padding:6px\">否</td><td style=\"padding:6px\">任何 HTML 小部件的即用型 HTML</td></tr><tr><td style=\"padding:6px\"><code>webhookUrl</code></td><td style=\"padding:6px\">是</td><td style=\"padding:6px\">否</td><td style=\"padding:6px\">配置的 webhook URL(只读)</td></tr></tbody></table>",
|
|
37
|
+
"help_stream": "对于实时 MJPEG 流,将 <code>stream</code> 设置为 <code>true</code>。使用 <code>streamPulse</code> 进行定时预览(请参阅设置上的<b>流脉冲自动关闭</b>)。<br><br><code>streamUrl</code> 状态为 VIS、VIS2 或仪表板中任何支持 HTML 的小部件提供即用型 HTML(例如 <code><img></code> 标记)。当流打开或关闭时它会自动更新。",
|
|
38
|
+
"load_cameras_button": "从 MotionEye 加载相机",
|
|
39
|
+
"load_cameras_help": "从 MotionEye 获取 /config/list 并添加表中尚未包含的摄像机。适配器实例必须正在运行。添加摄像机后保存配置并重启。",
|
|
40
|
+
"load_cameras_result_added": "新相机已添加到表中。保存配置并重新启动适配器实例。",
|
|
41
|
+
"load_cameras_result_none": "没有新相机 - 所有 MotionEye 相机均已在表中。",
|
|
21
42
|
"mode_off": "关闭 — 未检测到",
|
|
22
43
|
"mode_sharp": "Sharp——动作+视频录制",
|
|
23
44
|
"mode_still": "静止 — 仅运动触发",
|
|
@@ -37,6 +58,7 @@
|
|
|
37
58
|
"streamAutoOffMs": "流脉冲自动关闭(ms)",
|
|
38
59
|
"streamAutoOffMs_help": "仅由streamPulse使用-流在此持续时间后关闭(0=从不)",
|
|
39
60
|
"tab_cameras": "相机",
|
|
61
|
+
"tab_help": "帮助",
|
|
40
62
|
"tab_settings": "设置",
|
|
41
63
|
"useMotionEyeConfig": "通过 MotionEye 配置 API 控制",
|
|
42
64
|
"useMotionEyeConfig_help": "正常使用请保持启用。适配器将摄像头模式、Webhook URL 和流开关写入 MotionEye(端口 8765)。ioBroker 由此控制运动检测和直播流;MotionEye 网页界面会随之更新。仅在你完全手动配置 MotionEye 时才禁用。",
|
package/admin/jsonConfig.json
CHANGED
|
@@ -242,6 +242,27 @@
|
|
|
242
242
|
"marginBottom": "10px"
|
|
243
243
|
}
|
|
244
244
|
},
|
|
245
|
+
"_loadCameras": {
|
|
246
|
+
"type": "sendTo",
|
|
247
|
+
"label": "load_cameras_button",
|
|
248
|
+
"help": "load_cameras_help",
|
|
249
|
+
"command": "loadCameras",
|
|
250
|
+
"variant": "contained",
|
|
251
|
+
"useNative": true,
|
|
252
|
+
"showProcess": true,
|
|
253
|
+
"timeout": 60000,
|
|
254
|
+
"newLine": true,
|
|
255
|
+
"xs": 12,
|
|
256
|
+
"sm": 12,
|
|
257
|
+
"md": 6,
|
|
258
|
+
"lg": 6,
|
|
259
|
+
"xl": 6,
|
|
260
|
+
"jsonData": "{\"motionHost\":\"${data.motionHost}\",\"motionEyePort\":${data.motionEyePort},\"motionEyeUser\":\"${data.motionEyeUser}\",\"requestTimeoutMs\":${data.requestTimeoutMs},\"defaultMode\":\"${data.defaultMode}\",\"camerasPayload\":\"${encodeURIComponent(JSON.stringify(data.cameras || []))}\"}",
|
|
261
|
+
"result": {
|
|
262
|
+
"added": "load_cameras_result_added",
|
|
263
|
+
"none": "load_cameras_result_none"
|
|
264
|
+
}
|
|
265
|
+
},
|
|
245
266
|
"cameras": {
|
|
246
267
|
"type": "table",
|
|
247
268
|
"newLine": true,
|
|
@@ -256,14 +277,14 @@
|
|
|
256
277
|
"type": "text",
|
|
257
278
|
"attr": "name",
|
|
258
279
|
"title": "camera_name",
|
|
259
|
-
"width": "
|
|
280
|
+
"width": "18%",
|
|
260
281
|
"tooltip": "camera_name_help"
|
|
261
282
|
},
|
|
262
283
|
{
|
|
263
284
|
"type": "number",
|
|
264
285
|
"attr": "motionEyeId",
|
|
265
286
|
"title": "camera_motionEyeId",
|
|
266
|
-
"width": "
|
|
287
|
+
"width": "10%",
|
|
267
288
|
"min": 1,
|
|
268
289
|
"tooltip": "camera_motionEyeId_help"
|
|
269
290
|
},
|
|
@@ -271,15 +292,23 @@
|
|
|
271
292
|
"type": "text",
|
|
272
293
|
"attr": "id",
|
|
273
294
|
"title": "camera_id",
|
|
274
|
-
"width": "
|
|
295
|
+
"width": "14%",
|
|
275
296
|
"placeholder": "camera_id_placeholder",
|
|
276
297
|
"tooltip": "camera_id_help"
|
|
277
298
|
},
|
|
299
|
+
{
|
|
300
|
+
"type": "text",
|
|
301
|
+
"attr": "mediaFolder",
|
|
302
|
+
"title": "camera_mediaFolder",
|
|
303
|
+
"width": "14%",
|
|
304
|
+
"placeholder": "camera_mediaFolder_placeholder",
|
|
305
|
+
"tooltip": "camera_mediaFolder_help"
|
|
306
|
+
},
|
|
278
307
|
{
|
|
279
308
|
"type": "select",
|
|
280
309
|
"attr": "defaultMode",
|
|
281
310
|
"title": "camera_defaultMode",
|
|
282
|
-
"width": "
|
|
311
|
+
"width": "16%",
|
|
283
312
|
"options": [
|
|
284
313
|
{ "label": "mode_off", "value": "off" },
|
|
285
314
|
{ "label": "mode_still", "value": "still" },
|
|
@@ -297,6 +326,168 @@
|
|
|
297
326
|
]
|
|
298
327
|
}
|
|
299
328
|
}
|
|
329
|
+
},
|
|
330
|
+
"_help": {
|
|
331
|
+
"type": "panel",
|
|
332
|
+
"label": "tab_help",
|
|
333
|
+
"icon": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0iY3VycmVudENvbG9yIiBkPSJNMTUuMDcsMTEuMjVMMTQuMTcsMTIuMTdDMTMuNDUsMTIuODkgMTMsMTMuNSAxMywxNUgxMVYxNC41QzExLDEzLjM5IDExLjQ1LDEyLjM5IDEyLjE3LDExLjY3TDEzLjQxLDEwLjQxQzEzLjc4LDEwLjA1IDE0LDkuNTUgMTQsOUMxNCw3Ljg5IDEzLjEsNyAxMiw3QTIsMiAwIDAsMCAxMCw5SDhBNCw0IDAgMCwxIDEyLDVBNCs0IDAgMCwxIDE2LDlDMTYsOS44OCAxNS42NCwxMC42NyAxNS4wNywxMS4yNU0xMywxOUgxMVYxN0gxM00xMiwyQTEwLDEwIDAgMCwwIDIsMTJBMTAsMTAgMCAwLDAgMTIsMjJBMTAsMTAgMCAwLDAgMjIsMTJDMjIsNi40NyAxNy41LDIgMTIsMloiIC8+PC9zdmc+",
|
|
334
|
+
"items": {
|
|
335
|
+
"help_intro": {
|
|
336
|
+
"type": "staticText",
|
|
337
|
+
"text": "help_intro",
|
|
338
|
+
"format": "html",
|
|
339
|
+
"newLine": true,
|
|
340
|
+
"xs": 12,
|
|
341
|
+
"sm": 12,
|
|
342
|
+
"md": 12,
|
|
343
|
+
"lg": 12,
|
|
344
|
+
"xl": 12,
|
|
345
|
+
"style": {
|
|
346
|
+
"fontSize": "0.875rem",
|
|
347
|
+
"marginBottom": "16px"
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
"_helpSetupHeader": {
|
|
351
|
+
"type": "header",
|
|
352
|
+
"text": "help_section_setup",
|
|
353
|
+
"size": 4,
|
|
354
|
+
"newLine": true
|
|
355
|
+
},
|
|
356
|
+
"help_setup": {
|
|
357
|
+
"type": "staticText",
|
|
358
|
+
"text": "help_setup",
|
|
359
|
+
"format": "html",
|
|
360
|
+
"newLine": true,
|
|
361
|
+
"xs": 12,
|
|
362
|
+
"sm": 12,
|
|
363
|
+
"md": 12,
|
|
364
|
+
"lg": 12,
|
|
365
|
+
"xl": 12,
|
|
366
|
+
"style": {
|
|
367
|
+
"fontSize": "0.875rem",
|
|
368
|
+
"marginBottom": "16px"
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
"_helpConnectionHeader": {
|
|
372
|
+
"type": "header",
|
|
373
|
+
"text": "help_section_connection",
|
|
374
|
+
"size": 4,
|
|
375
|
+
"newLine": true
|
|
376
|
+
},
|
|
377
|
+
"help_connection": {
|
|
378
|
+
"type": "staticText",
|
|
379
|
+
"text": "help_connection",
|
|
380
|
+
"format": "html",
|
|
381
|
+
"newLine": true,
|
|
382
|
+
"xs": 12,
|
|
383
|
+
"sm": 12,
|
|
384
|
+
"md": 12,
|
|
385
|
+
"lg": 12,
|
|
386
|
+
"xl": 12,
|
|
387
|
+
"style": {
|
|
388
|
+
"fontSize": "0.875rem",
|
|
389
|
+
"marginBottom": "16px"
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
"_helpCamerasHeader": {
|
|
393
|
+
"type": "header",
|
|
394
|
+
"text": "help_section_cameras",
|
|
395
|
+
"size": 4,
|
|
396
|
+
"newLine": true
|
|
397
|
+
},
|
|
398
|
+
"help_cameras": {
|
|
399
|
+
"type": "staticText",
|
|
400
|
+
"text": "help_cameras",
|
|
401
|
+
"format": "html",
|
|
402
|
+
"newLine": true,
|
|
403
|
+
"xs": 12,
|
|
404
|
+
"sm": 12,
|
|
405
|
+
"md": 12,
|
|
406
|
+
"lg": 12,
|
|
407
|
+
"xl": 12,
|
|
408
|
+
"style": {
|
|
409
|
+
"fontSize": "0.875rem",
|
|
410
|
+
"marginBottom": "16px"
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
"_helpModesHeader": {
|
|
414
|
+
"type": "header",
|
|
415
|
+
"text": "help_section_modes",
|
|
416
|
+
"size": 4,
|
|
417
|
+
"newLine": true
|
|
418
|
+
},
|
|
419
|
+
"help_modes": {
|
|
420
|
+
"type": "staticText",
|
|
421
|
+
"text": "help_modes",
|
|
422
|
+
"format": "html",
|
|
423
|
+
"newLine": true,
|
|
424
|
+
"xs": 12,
|
|
425
|
+
"sm": 12,
|
|
426
|
+
"md": 12,
|
|
427
|
+
"lg": 12,
|
|
428
|
+
"xl": 12,
|
|
429
|
+
"style": {
|
|
430
|
+
"fontSize": "0.875rem",
|
|
431
|
+
"marginBottom": "16px"
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
"_helpStatesHeader": {
|
|
435
|
+
"type": "header",
|
|
436
|
+
"text": "help_section_states",
|
|
437
|
+
"size": 4,
|
|
438
|
+
"newLine": true
|
|
439
|
+
},
|
|
440
|
+
"help_states": {
|
|
441
|
+
"type": "staticText",
|
|
442
|
+
"text": "help_states",
|
|
443
|
+
"format": "html",
|
|
444
|
+
"newLine": true,
|
|
445
|
+
"xs": 12,
|
|
446
|
+
"sm": 12,
|
|
447
|
+
"md": 12,
|
|
448
|
+
"lg": 12,
|
|
449
|
+
"xl": 12,
|
|
450
|
+
"style": {
|
|
451
|
+
"fontSize": "0.875rem",
|
|
452
|
+
"marginBottom": "16px"
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
"_helpStreamHeader": {
|
|
456
|
+
"type": "header",
|
|
457
|
+
"text": "help_section_stream",
|
|
458
|
+
"size": 4,
|
|
459
|
+
"newLine": true
|
|
460
|
+
},
|
|
461
|
+
"help_stream": {
|
|
462
|
+
"type": "staticText",
|
|
463
|
+
"text": "help_stream",
|
|
464
|
+
"format": "html",
|
|
465
|
+
"newLine": true,
|
|
466
|
+
"xs": 12,
|
|
467
|
+
"sm": 12,
|
|
468
|
+
"md": 12,
|
|
469
|
+
"lg": 12,
|
|
470
|
+
"xl": 12,
|
|
471
|
+
"style": {
|
|
472
|
+
"fontSize": "0.875rem",
|
|
473
|
+
"marginBottom": "16px"
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
"help_readme": {
|
|
477
|
+
"type": "staticText",
|
|
478
|
+
"text": "help_readme",
|
|
479
|
+
"newLine": true,
|
|
480
|
+
"xs": 12,
|
|
481
|
+
"sm": 12,
|
|
482
|
+
"md": 12,
|
|
483
|
+
"lg": 12,
|
|
484
|
+
"xl": 12,
|
|
485
|
+
"style": {
|
|
486
|
+
"fontSize": "1rem",
|
|
487
|
+
"marginBottom": "16px"
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
300
491
|
}
|
|
301
492
|
}
|
|
302
493
|
}
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "motioneye",
|
|
4
|
-
"version": "0.1
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.2.1": {
|
|
7
|
+
"en": "Fixed adapter checker errors an warnings",
|
|
8
|
+
"de": "Adapterprüfungsfehler und Warnungen behoben",
|
|
9
|
+
"ru": "Исправлены ошибки и предупреждения проверки адаптера.",
|
|
10
|
+
"pt": "Erros e avisos do verificador de adaptadores corrigidos.",
|
|
11
|
+
"nl": "Fouten en waarschuwingen van de adaptercontrole zijn verholpen.",
|
|
12
|
+
"fr": "Correction des erreurs et avertissements du vérificateur d'adaptateur",
|
|
13
|
+
"it": "Risolti errori e avvisi del controllore dell'adattatore.",
|
|
14
|
+
"es": "Se corrigieron errores y advertencias del verificador de adaptadores.",
|
|
15
|
+
"pl": "Naprawiono błędy i ostrzeżenia modułu sprawdzającego adaptery",
|
|
16
|
+
"uk": "Виправлені помилки та попередження перевірки адаптера",
|
|
17
|
+
"zh-cn": "修复了适配器检查错误和警告。"
|
|
18
|
+
},
|
|
19
|
+
"0.2.0": {
|
|
20
|
+
"en": "Added optional per-camera media folder name under `/var/lib/motioneye` (written to MotionEye on adapter start)\nAdded camera load from MotionEye (merges `/config/list` into camera table)\nAdded Help-Tab with setup guide, modes, datapoints, and stream/inventwo notes",
|
|
21
|
+
"de": "Optionaler Medienordnername pro Kamera unter `/var/lib/motioneye` hinzugefügt (wird beim Start des Adapters in MotionEye geschrieben)\nKameradaten von MotionEye hinzugefügt (führt `/config/list` in die Kameratabelle ein)\nHilfe-Registerkarte mit Einrichtungsanleitung, Modi, Datenpunkten und Stream-/Inventwo-Hinweisen hinzugefügt",
|
|
22
|
+
"ru": "Добавлено необязательное имя папки с медиафайлами для каждой камеры в каталоге `/var/lib/motioneye` (записывается в MotionEye при запуске адаптера).\nДобавлена загрузка данных с камеры из MotionEye (объединяет `/config/list` с таблицей камер).\nДобавлена вкладка «Справка» с руководством по настройке, режимами, точками данных и примечаниями по stream/inventtwo.",
|
|
23
|
+
"pt": "Adicionada opção para definir o nome da pasta de mídia por câmera em `/var/lib/motioneye` (gravada no MotionEye na inicialização do adaptador).\nAdicionada a carga da câmera do MotionEye (mescla `/config/list` na tabela de câmeras).\nAdicionada aba de Ajuda com guia de configuração, modos, pontos de dados e notas de fluxo/invenção.",
|
|
24
|
+
"nl": "Er is een optionele mapnaam voor mediabestanden per camera toegevoegd onder `/var/lib/motioneye` (deze wordt naar MotionEye geschreven bij het opstarten van de adapter).\nCamera's geladen vanuit MotionEye (voegt `/config/list` samen met de cameratabel)\nEr is een Help-tabblad toegevoegd met een installatiehandleiding, informatie over modi, datapunten en opmerkingen over streamen/inventariseren.",
|
|
25
|
+
"fr": "Ajout d'un nom de dossier multimédia optionnel par caméra sous `/var/lib/motioneye` (écrit dans MotionEye au démarrage de l'adaptateur)\nAjout du chargement de la caméra depuis MotionEye (fusionne `/config/list` dans la table des caméras)\nAjout d'un onglet Aide contenant un guide d'installation, les modes, les points de données et des notes sur le flux/l'inventaire",
|
|
26
|
+
"it": "Aggiunto il nome opzionale della cartella multimediale per ciascuna telecamera in `/var/lib/motioneye` (scritto in MotionEye all'avvio dell'adattatore)\nAggiunto caricamento della telecamera da MotionEye (unisce `/config/list` nella tabella delle telecamere)\nAggiunta la scheda Aiuto con guida alla configurazione, modalità, punti dati e note su stream/inventtwo.",
|
|
27
|
+
"es": "Se agregó un nombre de carpeta de medios opcional por cámara en `/var/lib/motioneye` (se escribe en MotionEye al iniciar el adaptador).\nSe agregó la carga de la cámara desde MotionEye (fusiona `/config/list` en la tabla de cámaras).\nSe agregó una pestaña de Ayuda con guía de configuración, modos, puntos de datos y notas sobre stream/inventwo.",
|
|
28
|
+
"pl": "Dodano opcjonalną nazwę folderu multimedialnego dla każdej kamery w `/var/lib/motioneye` (zapisywana w MotionEye po uruchomieniu adaptera)\nDodano ładowanie kamery z MotionEye (scala `/config/list` z tabelą kamer)\nDodano zakładkę Pomoc z przewodnikiem konfiguracji, trybami, punktami danych i notatkami dotyczącymi strumienia/inventwo",
|
|
29
|
+
"uk": "Додано необов'язкову назву папки медіа для кожної камери в `/var/lib/motioneye` (записується в MotionEye під час запуску адаптера)\nДодано завантаження камери з MotionEye (об'єднання `/config/list` з таблицею камер)\nДодано вкладку «Довідка» з посібником з налаштування, режимами, точками даних та нотатками щодо потоку/винаходу.",
|
|
30
|
+
"zh-cn": "在 `/var/lib/motioneye` 下添加了可选的每台摄像机的媒体文件夹名称(在适配器启动时写入 MotionEye)\n添加了来自 MotionEye 的摄像头加载信息(将 `/config/list` 合并到摄像头表中)\n新增帮助选项卡,包含设置指南、模式、数据点和流/库存说明"
|
|
31
|
+
},
|
|
6
32
|
"0.1.2": {
|
|
7
33
|
"en": "Clarified admin help for useMotionEyeConfig (required for mode, webhooks, and stream control — not only MotionEye web UI)",
|
|
8
34
|
"de": "Präzisierte Administratorhilfe für useMotionEyeConfig (erforderlich für Modus, Webhooks und Stream-Steuerung – nicht nur für die MotionEye-Weboberfläche)",
|
|
@@ -105,6 +131,7 @@
|
|
|
105
131
|
"mode": "daemon",
|
|
106
132
|
"type": "hardware",
|
|
107
133
|
"compact": true,
|
|
134
|
+
"messagebox": true,
|
|
108
135
|
"connectionType": "local",
|
|
109
136
|
"dataSource": "poll",
|
|
110
137
|
"adminUI": {
|
|
@@ -144,6 +171,12 @@
|
|
|
144
171
|
"defaultMode": "off",
|
|
145
172
|
"cameras": []
|
|
146
173
|
},
|
|
174
|
+
"protectedNative": [
|
|
175
|
+
"motionEyePassword"
|
|
176
|
+
],
|
|
177
|
+
"encryptedNative": [
|
|
178
|
+
"motionEyePassword"
|
|
179
|
+
],
|
|
147
180
|
"objects": [],
|
|
148
181
|
"instanceObjects": [
|
|
149
182
|
{
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { MOTIONEYE_MEDIA_BASE, sanitizeMediaFolderName } = require('./mediaStorage');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Extract custom media folder name from a MotionEye camera config entry.
|
|
7
|
+
* @param {Record<string, unknown>} camera
|
|
8
|
+
* @returns {string}
|
|
9
|
+
*/
|
|
10
|
+
function extractMediaFolderFromMotionEyeConfig(camera) {
|
|
11
|
+
const rootDir = String(camera?.root_directory || '').trim();
|
|
12
|
+
if (!rootDir) {
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const prefix = `${MOTIONEYE_MEDIA_BASE}/`;
|
|
17
|
+
if (!rootDir.startsWith(prefix)) {
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const folder = rootDir.slice(prefix.length);
|
|
22
|
+
if (!folder || /^Camera\d+$/i.test(folder)) {
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return sanitizeMediaFolderName(folder);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {Record<string, unknown>} entry
|
|
31
|
+
* @param {string} [defaultMode]
|
|
32
|
+
* @returns {import('./cameraRegistry').NativeCameraConfig|null}
|
|
33
|
+
*/
|
|
34
|
+
function mapMotionEyeCamera(entry, defaultMode) {
|
|
35
|
+
const motionEyeId = Number(entry.id);
|
|
36
|
+
if (!motionEyeId || Number.isNaN(motionEyeId)) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const name = String(entry.name || `Camera ${motionEyeId}`).trim();
|
|
41
|
+
if (!name) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
name,
|
|
47
|
+
motionEyeId,
|
|
48
|
+
id: '',
|
|
49
|
+
mediaFolder: extractMediaFolderFromMotionEyeConfig(entry),
|
|
50
|
+
defaultMode: defaultMode || 'off',
|
|
51
|
+
enabled: true,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Add MotionEye cameras that are not yet in the admin table.
|
|
57
|
+
*
|
|
58
|
+
* @param {import('./cameraRegistry').NativeCameraConfig[]} existingCameras
|
|
59
|
+
* @param {Record<string, unknown>[]} motionEyeList
|
|
60
|
+
* @param {string} [defaultMode]
|
|
61
|
+
* @returns {{ cameras: import('./cameraRegistry').NativeCameraConfig[], added: number, total: number }}
|
|
62
|
+
*/
|
|
63
|
+
function mergeMotionEyeCameras(existingCameras, motionEyeList, defaultMode = 'off') {
|
|
64
|
+
const cameras = Array.isArray(existingCameras) ? existingCameras.map(entry => ({ ...entry })) : [];
|
|
65
|
+
|
|
66
|
+
const knownIds = new Set(
|
|
67
|
+
cameras.map(entry => Number(entry?.motionEyeId)).filter(id => !Number.isNaN(id) && id > 0),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
let added = 0;
|
|
71
|
+
const list = Array.isArray(motionEyeList) ? motionEyeList : [];
|
|
72
|
+
|
|
73
|
+
for (const entry of list) {
|
|
74
|
+
if (!entry || typeof entry !== 'object') {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const mapped = mapMotionEyeCamera(/** @type {Record<string, unknown>} */ (entry), defaultMode);
|
|
79
|
+
if (!mapped || knownIds.has(mapped.motionEyeId)) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
cameras.push(mapped);
|
|
84
|
+
knownIds.add(mapped.motionEyeId);
|
|
85
|
+
added += 1;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return { cameras, added, total: list.length };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Parse admin sendTo payload (jsonData may encode the cameras table).
|
|
93
|
+
*
|
|
94
|
+
* @param {unknown} message
|
|
95
|
+
* @returns {Record<string, unknown>}
|
|
96
|
+
*/
|
|
97
|
+
function parseLoadCamerasMessage(message) {
|
|
98
|
+
if (typeof message === 'string') {
|
|
99
|
+
try {
|
|
100
|
+
return parseLoadCamerasMessage(JSON.parse(message));
|
|
101
|
+
} catch {
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!message || typeof message !== 'object') {
|
|
107
|
+
return {};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** @type {Record<string, unknown>} */
|
|
111
|
+
const payload = { ...message };
|
|
112
|
+
|
|
113
|
+
if (typeof payload.camerasPayload === 'string') {
|
|
114
|
+
try {
|
|
115
|
+
payload.cameras = JSON.parse(decodeURIComponent(payload.camerasPayload));
|
|
116
|
+
} catch {
|
|
117
|
+
// ignore invalid admin payload
|
|
118
|
+
}
|
|
119
|
+
delete payload.camerasPayload;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return payload;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
module.exports = {
|
|
126
|
+
extractMediaFolderFromMotionEyeConfig,
|
|
127
|
+
mapMotionEyeCamera,
|
|
128
|
+
mergeMotionEyeCameras,
|
|
129
|
+
parseLoadCamerasMessage,
|
|
130
|
+
};
|