iobroker.agent-dvr 0.2.1 → 0.3.0

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.
@@ -131,5 +131,9 @@
131
131
  "cfgGo2rtcUrl_tt": "URL base del servidor go2rtc, p. ej. http://192.168.1.1:1984",
132
132
  "cfgGo2rtcMapping_tt": "Selecciona la fuente de stream por cámara: MJPEG, MP4/FLV (vía AgentDVR) o un stream go2rtc.",
133
133
  "cfgIpMissing": "La dirección IP de AgentDVR es obligatoria",
134
- "cfgNoCamerasFound": "No se encontraron cámaras — ¿el adaptador está configurado y ha realizado al menos un sondeo?"
135
- }
134
+ "cfgNoCamerasFound": "No se encontraron cámaras — ¿el adaptador está configurado y ha realizado al menos un sondeo?",
135
+ "loadingCamerasAndStreams": "Cargando cámaras y streams…",
136
+ "cfgCameraColumn": "Cámara AgentDVR",
137
+ "cfgStreamSourceColumn": "Fuente de stream",
138
+ "reload": "Recargar"
139
+ }
@@ -131,5 +131,9 @@
131
131
  "cfgGo2rtcUrl_tt": "URL de base du serveur go2rtc, par ex. http://192.168.1.1:1984",
132
132
  "cfgGo2rtcMapping_tt": "Sélectionnez la source de flux par caméra : MJPEG, MP4/FLV (via AgentDVR) ou un flux go2rtc.",
133
133
  "cfgIpMissing": "L'adresse IP AgentDVR est requise",
134
- "cfgNoCamerasFound": "Aucune caméra trouvée — l'adaptateur est-il configuré et a-t-il effectué au moins un sondage ?"
135
- }
134
+ "cfgNoCamerasFound": "Aucune caméra trouvée — l'adaptateur est-il configuré et a-t-il effectué au moins un sondage ?",
135
+ "loadingCamerasAndStreams": "Chargement des caméras et des flux…",
136
+ "cfgCameraColumn": "Caméra AgentDVR",
137
+ "cfgStreamSourceColumn": "Source du flux",
138
+ "reload": "Recharger"
139
+ }
@@ -131,5 +131,9 @@
131
131
  "cfgGo2rtcUrl_tt": "URL base del server go2rtc, es. http://192.168.1.1:1984",
132
132
  "cfgGo2rtcMapping_tt": "Seleziona la sorgente del flusso per telecamera: MJPEG, MP4/FLV (tramite AgentDVR) o un flusso go2rtc.",
133
133
  "cfgIpMissing": "L'indirizzo IP di AgentDVR è obbligatorio",
134
- "cfgNoCamerasFound": "Nessuna telecamera trovata — l'adattatore è configurato e ha eseguito almeno un polling?"
135
- }
134
+ "cfgNoCamerasFound": "Nessuna telecamera trovata — l'adattatore è configurato e ha eseguito almeno un polling?",
135
+ "loadingCamerasAndStreams": "Caricamento telecamere e stream…",
136
+ "cfgCameraColumn": "Telecamera AgentDVR",
137
+ "cfgStreamSourceColumn": "Sorgente stream",
138
+ "reload": "Ricarica"
139
+ }
@@ -131,5 +131,9 @@
131
131
  "cfgGo2rtcUrl_tt": "Basis-URL van de go2rtc-server, bijv. http://192.168.1.1:1984",
132
132
  "cfgGo2rtcMapping_tt": "Selecteer de streambron per camera: MJPEG, MP4/FLV (via AgentDVR) of een go2rtc-stream.",
133
133
  "cfgIpMissing": "Het AgentDVR IP-adres is vereist",
134
- "cfgNoCamerasFound": "Geen camera's gevonden — is de adapter geconfigureerd en heeft hij minstens één keer gepolld?"
135
- }
134
+ "cfgNoCamerasFound": "Geen camera's gevonden — is de adapter geconfigureerd en heeft hij minstens één keer gepolld?",
135
+ "loadingCamerasAndStreams": "Camera's en streams laden…",
136
+ "cfgCameraColumn": "AgentDVR Camera",
137
+ "cfgStreamSourceColumn": "Streambron",
138
+ "reload": "Herladen"
139
+ }
@@ -131,5 +131,9 @@
131
131
  "cfgGo2rtcUrl_tt": "Bazowy URL serwera go2rtc, np. http://192.168.1.1:1984",
132
132
  "cfgGo2rtcMapping_tt": "Wybierz źródło strumienia dla każdej kamery: MJPEG, MP4/FLV (przez AgentDVR) lub strumień go2rtc.",
133
133
  "cfgIpMissing": "Adres IP AgentDVR jest wymagany",
134
- "cfgNoCamerasFound": "Nie znaleziono kamer — czy adapter jest skonfigurowany i przeprowadził co najmniej jedno odpytywanie?"
135
- }
134
+ "cfgNoCamerasFound": "Nie znaleziono kamer — czy adapter jest skonfigurowany i przeprowadził co najmniej jedno odpytywanie?",
135
+ "loadingCamerasAndStreams": "Ładowanie kamer i strumieni…",
136
+ "cfgCameraColumn": "Kamera AgentDVR",
137
+ "cfgStreamSourceColumn": "Źródło strumienia",
138
+ "reload": "Odśwież"
139
+ }
@@ -131,5 +131,9 @@
131
131
  "cfgGo2rtcUrl_tt": "URL base do servidor go2rtc, ex. http://192.168.1.1:1984",
132
132
  "cfgGo2rtcMapping_tt": "Selecione a fonte de fluxo por câmera: MJPEG, MP4/FLV (via AgentDVR) ou um fluxo go2rtc.",
133
133
  "cfgIpMissing": "O endereço IP do AgentDVR é obrigatório",
134
- "cfgNoCamerasFound": "Nenhuma câmera encontrada — o adaptador está configurado e realizou pelo menos uma consulta?"
135
- }
134
+ "cfgNoCamerasFound": "Nenhuma câmera encontrada — o adaptador está configurado e realizou pelo menos uma consulta?",
135
+ "loadingCamerasAndStreams": "Carregando câmeras e streams…",
136
+ "cfgCameraColumn": "Câmera AgentDVR",
137
+ "cfgStreamSourceColumn": "Fonte de stream",
138
+ "reload": "Recarregar"
139
+ }
@@ -131,5 +131,9 @@
131
131
  "cfgGo2rtcUrl_tt": "Базовый URL сервера go2rtc, например http://192.168.1.1:1984",
132
132
  "cfgGo2rtcMapping_tt": "Выберите источник потока для каждой камеры: MJPEG, MP4/FLV (через AgentDVR) или поток go2rtc.",
133
133
  "cfgIpMissing": "IP-адрес AgentDVR обязателен",
134
- "cfgNoCamerasFound": "Камеры не найдены — настроен ли адаптер и выполнен ли хотя бы один опрос?"
135
- }
134
+ "cfgNoCamerasFound": "Камеры не найдены — настроен ли адаптер и выполнен ли хотя бы один опрос?",
135
+ "loadingCamerasAndStreams": "Загрузка камер и потоков…",
136
+ "cfgCameraColumn": "Камера AgentDVR",
137
+ "cfgStreamSourceColumn": "Источник потока",
138
+ "reload": "Обновить"
139
+ }
@@ -131,5 +131,9 @@
131
131
  "cfgGo2rtcUrl_tt": "Базова URL-адреса сервера go2rtc, напр. http://192.168.1.1:1984",
132
132
  "cfgGo2rtcMapping_tt": "Виберіть джерело потоку для кожної камери: MJPEG, MP4/FLV (через AgentDVR) або потік go2rtc.",
133
133
  "cfgIpMissing": "IP-адреса AgentDVR є обов'язковою",
134
- "cfgNoCamerasFound": "Камери не знайдено — адаптер налаштовано та виконано принаймні один опит?"
135
- }
134
+ "cfgNoCamerasFound": "Камери не знайдено — адаптер налаштовано та виконано принаймні один опит?",
135
+ "loadingCamerasAndStreams": "Завантаження камер і потоків…",
136
+ "cfgCameraColumn": "Камера AgentDVR",
137
+ "cfgStreamSourceColumn": "Джерело потоку",
138
+ "reload": "Оновити"
139
+ }
@@ -131,5 +131,9 @@
131
131
  "cfgGo2rtcUrl_tt": "go2rtc 服务器的基础 URL,例如 http://192.168.1.1:1984",
132
132
  "cfgGo2rtcMapping_tt": "为每个摄像头选择流来源:MJPEG、MP4/FLV(通过AgentDVR)或go2rtc流。",
133
133
  "cfgIpMissing": "AgentDVR IP地址为必填项",
134
- "cfgNoCamerasFound": "未找到摄像头 — 适配器是否已配置并至少轮询过一次?"
135
- }
134
+ "cfgNoCamerasFound": "未找到摄像头 — 适配器是否已配置并至少轮询过一次?",
135
+ "loadingCamerasAndStreams": "正在加载摄像头和流…",
136
+ "cfgCameraColumn": "AgentDVR 摄像头",
137
+ "cfgStreamSourceColumn": "流来源",
138
+ "reload": "重新加载"
139
+ }
@@ -18,7 +18,7 @@
18
18
  };
19
19
  document.head.appendChild(script);
20
20
  </script>
21
- <script type="module" crossorigin src="./assets/index-DD1mpQy7.js"></script>
21
+ <script type="module" crossorigin src="./assets/index-DFh6AKdK.js"></script>
22
22
  </head>
23
23
  <body>
24
24
  <noscript>You need to enable JavaScript to run this app.</noscript>
package/build/main.js CHANGED
@@ -45,6 +45,10 @@ const CAM_COMMANDS = [
45
45
  },
46
46
  { id: "recOnAlert", path: "/command/recordOnAlertOn", params: ["oid", "ot"], name: "Record on alert: on" },
47
47
  { id: "recOnDetect", path: "/command/recordOnDetectOn", params: ["oid", "ot"], name: "Record on detect: on" },
48
+ { id: "scheduleOn", path: "/command/scheduleOn", params: ["oid", "ot"], name: "Enable schedule" },
49
+ { id: "scheduleOff", path: "/command/scheduleOff", params: ["oid", "ot"], name: "Disable schedule" },
50
+ { id: "detectorOn", path: "/command/switchDetector?on=true", params: ["oid", "ot"], name: "Enable detector" },
51
+ { id: "detectorOff", path: "/command/switchDetector?on=false", params: ["oid", "ot"], name: "Disable detector" },
48
52
  { id: "purge", path: "/command/purge", params: ["oid", "ot"], name: "Purge folder (caution!)" }
49
53
  ];
50
54
  const SYS_COMMANDS = [
@@ -617,6 +621,19 @@ class AgentDvr extends utils.Adapter {
617
621
  ensureButton(id, name, entry) {
618
622
  return this.ensureControl(id, name, entry, "button");
619
623
  }
624
+ async ensureLevel(id, name, entry, min, max) {
625
+ if (!this.ensuredFolders.has(id)) {
626
+ await this.ensurePath(id);
627
+ await this.setObjectNotExistsAsync(id, {
628
+ type: "state",
629
+ common: { name, type: "number", role: "level", read: true, write: true, min, max },
630
+ native: {}
631
+ });
632
+ await this.setStateAsync(id, { val: 0, ack: true });
633
+ this.ensuredFolders.add(id);
634
+ }
635
+ this.registry.set(id, entry);
636
+ }
620
637
  async ensureSelector(id, name, entry, states) {
621
638
  if (!this.ensuredFolders.has(id)) {
622
639
  await this.ensurePath(id);
@@ -756,8 +773,9 @@ class AgentDvr extends utils.Adapter {
756
773
  await this.flattenWrite(d.raw, fid, 0);
757
774
  await this.writeStatusDps(d, fid);
758
775
  await this.ensureFolder(`${fid}.control`, "Control", "channel");
776
+ const CAM_ONLY = /* @__PURE__ */ new Set(["snapshot", "objectDetectOn", "objectDetectOff"]);
759
777
  for (const c of CAM_COMMANDS) {
760
- if (c.id === "snapshot" && d.ot !== 2) {
778
+ if (CAM_ONLY.has(c.id) && d.ot !== 2) {
761
779
  continue;
762
780
  }
763
781
  await this.ensureButton(`${fid}.control.${c.id}`, c.name, {
@@ -784,12 +802,41 @@ class AgentDvr extends utils.Adapter {
784
802
  }
785
803
  }
786
804
  }
787
- if (this.config.enableUrls && d.ot === 2) {
805
+ if (d.ot === 2) {
806
+ const sfx = { kind: "levelCmd", path: "/command/setSensitivity", oid: d.oid, ot: d.ot };
807
+ await this.ensureLevel(
808
+ `${fid}.control.sensitivityMin`,
809
+ "Sensitivity min (0-100)",
810
+ { ...sfx, valueParam: "min" },
811
+ 0,
812
+ 100
813
+ );
814
+ await this.ensureLevel(
815
+ `${fid}.control.sensitivityMax`,
816
+ "Sensitivity max (0-100)",
817
+ { ...sfx, valueParam: "max" },
818
+ 0,
819
+ 100
820
+ );
821
+ await this.ensureLevel(
822
+ `${fid}.control.sensitivityGain`,
823
+ "Sensitivity gain (0-100)",
824
+ { ...sfx, valueParam: "gain" },
825
+ 0,
826
+ 100
827
+ );
828
+ }
829
+ if (this.config.enableUrls) {
788
830
  await this.ensureFolder(`${fid}.urls`, "URLs", "channel");
789
- await this.writeLeaf(`${fid}.urls.snapshot`, `${this.baseUrl}/grab.jpg?oid=${d.oid}`);
790
- await this.writeLeaf(`${fid}.urls.photo`, `${this.baseUrl}/photo.jpg?oid=${d.oid}`);
791
- await this.writeLeaf(`${fid}.urls.mjpeg`, `${this.baseUrl}/video.mjpg?oids=${d.oid}`);
792
- await this.writeLeaf(`${fid}.urls.mp4`, `${this.baseUrl}/video.mp4?oids=${d.oid}`);
831
+ if (d.ot === 2) {
832
+ await this.writeLeaf(`${fid}.urls.snapshot`, `${this.baseUrl}/grab.jpg?oid=${d.oid}`);
833
+ await this.writeLeaf(`${fid}.urls.photo`, `${this.baseUrl}/photo.jpg?oid=${d.oid}`);
834
+ await this.writeLeaf(`${fid}.urls.mjpeg`, `${this.baseUrl}/video.mjpg?oids=${d.oid}`);
835
+ await this.writeLeaf(`${fid}.urls.mp4`, `${this.baseUrl}/video.mp4?oids=${d.oid}`);
836
+ } else if (d.ot === 1) {
837
+ await this.writeLeaf(`${fid}.urls.audio_mp3`, `${this.baseUrl}/audio.mp3?oid=${d.oid}`);
838
+ await this.writeLeaf(`${fid}.urls.audio_ogg`, `${this.baseUrl}/audio.ogg?oid=${d.oid}`);
839
+ }
793
840
  }
794
841
  if (d.ot === 2) {
795
842
  const snapId = `${fid}.snapshot_b64`;
@@ -1288,7 +1335,9 @@ class AgentDvr extends utils.Adapter {
1288
1335
  qs.push(`ot=${encodeURIComponent(String(entry.ot))}`);
1289
1336
  }
1290
1337
  }
1291
- return (entry.path || "") + (qs.length ? `?${qs.join("&")}` : "");
1338
+ const base = entry.path || "";
1339
+ const sep = base.includes("?") ? "&" : "?";
1340
+ return base + (qs.length ? `${sep}${qs.join("&")}` : "");
1292
1341
  }
1293
1342
  async clearPtzSiblings(stateId) {
1294
1343
  const prefix = stateId.slice(0, stateId.lastIndexOf(".") + 1);
@@ -1318,6 +1367,21 @@ class AgentDvr extends utils.Adapter {
1318
1367
  }
1319
1368
  return;
1320
1369
  }
1370
+ if (entry.kind === "levelCmd") {
1371
+ const num = typeof val === "number" ? val : parseFloat(String(val != null ? val : ""));
1372
+ if (!isNaN(num)) {
1373
+ const url2 = `${entry.path}?oid=${encodeURIComponent(String(entry.oid))}&ot=${encodeURIComponent(String(entry.ot))}&${entry.valueParam}=${Math.round(num)}`;
1374
+ const cmdRes2 = await this.apiGet(url2);
1375
+ if (cmdRes2.ok) {
1376
+ this.log.debug(`OK: ${url2}`);
1377
+ await this.setStateAsync(relId, { val: Math.round(num), ack: true });
1378
+ } else {
1379
+ this.log.warn(`Command failed (${url2}): ${cmdRes2.error}`);
1380
+ }
1381
+ this.scheduleRefresh();
1382
+ }
1383
+ return;
1384
+ }
1321
1385
  if (entry.kind === "snapshotB64") {
1322
1386
  const snapId = `${entry.fid}.snapshot_b64`;
1323
1387
  await this.fetchSnapshotB64(entry.oid, snapId);