iobroker.agent-dvr 0.2.2 → 0.4.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.
@@ -135,5 +135,8 @@
135
135
  "loadingCamerasAndStreams": "Lade Kameras und Streams…",
136
136
  "cfgCameraColumn": "AgentDVR Kamera",
137
137
  "cfgStreamSourceColumn": "Stream-Quelle",
138
- "reload": "Neu laden"
139
- }
138
+ "reload": "Neu laden",
139
+ "hdrProxy": "Proxy",
140
+ "cfgEnableStreamProxy": "MJPEG-Proxy",
141
+ "cfgEnableStreamProxy_tt": "MJPEG- und Snapshot-URLs über ioBroker leiten (nur im MJPEG-Stream-Modus nötig — FLV und go2rtc laufen immer über ioBroker)"
142
+ }
@@ -135,5 +135,8 @@
135
135
  "loadingCamerasAndStreams": "Loading cameras and streams…",
136
136
  "cfgCameraColumn": "AgentDVR Camera",
137
137
  "cfgStreamSourceColumn": "Stream Source",
138
- "reload": "Reload"
139
- }
138
+ "reload": "Reload",
139
+ "hdrProxy": "Proxy",
140
+ "cfgEnableStreamProxy": "MJPEG proxy",
141
+ "cfgEnableStreamProxy_tt": "Route MJPEG and snapshot URLs through ioBroker (only needed for MJPEG stream mode — FLV and go2rtc are always proxied)"
142
+ }
@@ -135,5 +135,8 @@
135
135
  "loadingCamerasAndStreams": "Cargando cámaras y streams…",
136
136
  "cfgCameraColumn": "Cámara AgentDVR",
137
137
  "cfgStreamSourceColumn": "Fuente de stream",
138
- "reload": "Recargar"
139
- }
138
+ "reload": "Recargar",
139
+ "hdrProxy": "Proxy",
140
+ "cfgEnableStreamProxy": "Proxy MJPEG",
141
+ "cfgEnableStreamProxy_tt": "Enrutar MJPEG y snapshots a través de ioBroker (solo en modo MJPEG — FLV y go2rtc siempre se enrutan)"
142
+ }
@@ -135,5 +135,8 @@
135
135
  "loadingCamerasAndStreams": "Chargement des caméras et des flux…",
136
136
  "cfgCameraColumn": "Caméra AgentDVR",
137
137
  "cfgStreamSourceColumn": "Source du flux",
138
- "reload": "Recharger"
139
- }
138
+ "reload": "Recharger",
139
+ "hdrProxy": "Proxy",
140
+ "cfgEnableStreamProxy": "Proxy MJPEG",
141
+ "cfgEnableStreamProxy_tt": "Acheminer MJPEG et instantanés via ioBroker (uniquement en mode MJPEG — FLV et go2rtc sont toujours proxied)"
142
+ }
@@ -135,5 +135,8 @@
135
135
  "loadingCamerasAndStreams": "Caricamento telecamere e stream…",
136
136
  "cfgCameraColumn": "Telecamera AgentDVR",
137
137
  "cfgStreamSourceColumn": "Sorgente stream",
138
- "reload": "Ricarica"
139
- }
138
+ "reload": "Ricarica",
139
+ "hdrProxy": "Proxy",
140
+ "cfgEnableStreamProxy": "Proxy MJPEG",
141
+ "cfgEnableStreamProxy_tt": "Instradare MJPEG e snapshot tramite ioBroker (solo in modalità MJPEG — FLV e go2rtc sono sempre proxied)"
142
+ }
@@ -135,5 +135,8 @@
135
135
  "loadingCamerasAndStreams": "Camera's en streams laden…",
136
136
  "cfgCameraColumn": "AgentDVR Camera",
137
137
  "cfgStreamSourceColumn": "Streambron",
138
- "reload": "Herladen"
139
- }
138
+ "reload": "Herladen",
139
+ "hdrProxy": "Proxy",
140
+ "cfgEnableStreamProxy": "MJPEG-proxy",
141
+ "cfgEnableStreamProxy_tt": "MJPEG- en snapshot-URLs via ioBroker routen (alleen nodig in MJPEG-modus — FLV en go2rtc worden altijd geproxied)"
142
+ }
@@ -135,5 +135,8 @@
135
135
  "loadingCamerasAndStreams": "Ładowanie kamer i strumieni…",
136
136
  "cfgCameraColumn": "Kamera AgentDVR",
137
137
  "cfgStreamSourceColumn": "Źródło strumienia",
138
- "reload": "Odśwież"
139
- }
138
+ "reload": "Odśwież",
139
+ "hdrProxy": "Proxy",
140
+ "cfgEnableStreamProxy": "Proxy MJPEG",
141
+ "cfgEnableStreamProxy_tt": "Kieruj MJPEG i migawki przez ioBroker (tylko w trybie MJPEG — FLV i go2rtc są zawsze proxied)"
142
+ }
@@ -135,5 +135,8 @@
135
135
  "loadingCamerasAndStreams": "Carregando câmeras e streams…",
136
136
  "cfgCameraColumn": "Câmera AgentDVR",
137
137
  "cfgStreamSourceColumn": "Fonte de stream",
138
- "reload": "Recarregar"
139
- }
138
+ "reload": "Recarregar",
139
+ "hdrProxy": "Proxy",
140
+ "cfgEnableStreamProxy": "Proxy MJPEG",
141
+ "cfgEnableStreamProxy_tt": "Rotear MJPEG e snapshots pelo ioBroker (necessário apenas no modo MJPEG — FLV e go2rtc já são sempre proxied)"
142
+ }
@@ -135,5 +135,8 @@
135
135
  "loadingCamerasAndStreams": "Загрузка камер и потоков…",
136
136
  "cfgCameraColumn": "Камера AgentDVR",
137
137
  "cfgStreamSourceColumn": "Источник потока",
138
- "reload": "Обновить"
139
- }
138
+ "reload": "Обновить",
139
+ "hdrProxy": "Прокси",
140
+ "cfgEnableStreamProxy": "MJPEG-прокси",
141
+ "cfgEnableStreamProxy_tt": "Маршрутизировать MJPEG и снимки через ioBroker (только для режима MJPEG — FLV и go2rtc всегда проксируются)"
142
+ }
@@ -135,5 +135,8 @@
135
135
  "loadingCamerasAndStreams": "Завантаження камер і потоків…",
136
136
  "cfgCameraColumn": "Камера AgentDVR",
137
137
  "cfgStreamSourceColumn": "Джерело потоку",
138
- "reload": "Оновити"
139
- }
138
+ "reload": "Оновити",
139
+ "hdrProxy": "Проксі",
140
+ "cfgEnableStreamProxy": "MJPEG-проксі",
141
+ "cfgEnableStreamProxy_tt": "Маршрутизувати MJPEG і знімки через ioBroker (лише для режиму MJPEG — FLV і go2rtc завжди проксіюються)"
142
+ }
@@ -135,5 +135,8 @@
135
135
  "loadingCamerasAndStreams": "正在加载摄像头和流…",
136
136
  "cfgCameraColumn": "AgentDVR 摄像头",
137
137
  "cfgStreamSourceColumn": "流来源",
138
- "reload": "重新加载"
139
- }
138
+ "reload": "重新加载",
139
+ "hdrProxy": "代理",
140
+ "cfgEnableStreamProxy": "MJPEG 代理",
141
+ "cfgEnableStreamProxy_tt": "通过 ioBroker 路由 MJPEG 和快照(仅 MJPEG 模式需要 — FLV 和 go2rtc 始终通过代理)"
142
+ }
@@ -18,7 +18,7 @@
18
18
  };
19
19
  document.head.appendChild(script);
20
20
  </script>
21
- <script type="module" crossorigin src="./assets/index-DFh6AKdK.js"></script>
21
+ <script type="module" crossorigin src="./assets/index-B13Ujb6j.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);