iobroker.agent-dvr 0.0.2 → 0.0.3
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.de.md +195 -0
- package/README.md +160 -88
- package/admin/i18n/de.json +3 -2
- package/admin/i18n/en.json +3 -2
- package/admin/i18n/es.json +3 -2
- package/admin/i18n/fr.json +3 -2
- package/admin/i18n/it.json +3 -2
- package/admin/i18n/nl.json +3 -2
- package/admin/i18n/pl.json +3 -2
- package/admin/i18n/pt.json +3 -2
- package/admin/i18n/ru.json +3 -2
- package/admin/i18n/uk.json +3 -2
- package/admin/i18n/zh-cn.json +3 -2
- package/admin/jsonConfig.json +5 -0
- package/build/main.js +159 -0
- package/build/main.js.map +3 -3
- package/io-package.json +15 -1
- package/package.json +3 -3
package/build/main.js
CHANGED
|
@@ -278,6 +278,7 @@ class AgentDvr extends utils.Adapter {
|
|
|
278
278
|
registry = /* @__PURE__ */ new Map();
|
|
279
279
|
ptzActive = /* @__PURE__ */ new Map();
|
|
280
280
|
widgetSig = {};
|
|
281
|
+
profileSig = "";
|
|
281
282
|
lastEventFn = {};
|
|
282
283
|
camAspect = {};
|
|
283
284
|
devById = /* @__PURE__ */ new Map();
|
|
@@ -382,6 +383,43 @@ class AgentDvr extends utils.Adapter {
|
|
|
382
383
|
}
|
|
383
384
|
});
|
|
384
385
|
}
|
|
386
|
+
apiGetBuffer(path) {
|
|
387
|
+
return new Promise((resolve) => {
|
|
388
|
+
const timeout = Math.max(1e3, Math.min(3e4, this.config.httpTimeoutMs || 8e3));
|
|
389
|
+
const opts = {
|
|
390
|
+
hostname: this.config.ip,
|
|
391
|
+
port: this.config.port || 8090,
|
|
392
|
+
path,
|
|
393
|
+
method: "GET",
|
|
394
|
+
timeout
|
|
395
|
+
};
|
|
396
|
+
if (this.authHeader) {
|
|
397
|
+
opts.headers = { Authorization: this.authHeader };
|
|
398
|
+
}
|
|
399
|
+
try {
|
|
400
|
+
const req = http.request(opts, (res) => {
|
|
401
|
+
const chunks = [];
|
|
402
|
+
res.on("data", (c) => chunks.push(c));
|
|
403
|
+
res.on("end", () => {
|
|
404
|
+
if (res.statusCode && res.statusCode >= 400) {
|
|
405
|
+
resolve({ ok: false, error: `HTTP ${res.statusCode}` });
|
|
406
|
+
} else {
|
|
407
|
+
resolve({ ok: true, data: Buffer.concat(chunks) });
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
res.on("error", (e) => resolve({ ok: false, error: e.message }));
|
|
411
|
+
});
|
|
412
|
+
req.on("error", (e) => resolve({ ok: false, error: e.message }));
|
|
413
|
+
req.on("timeout", () => {
|
|
414
|
+
req.destroy();
|
|
415
|
+
resolve({ ok: false, error: "timeout" });
|
|
416
|
+
});
|
|
417
|
+
req.end();
|
|
418
|
+
} catch (e) {
|
|
419
|
+
resolve({ ok: false, error: String(e.message || e) });
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}
|
|
385
423
|
async ensureFolder(id, name, type = "channel") {
|
|
386
424
|
if (this.ensuredFolders.has(id)) {
|
|
387
425
|
return;
|
|
@@ -471,6 +509,28 @@ class AgentDvr extends utils.Adapter {
|
|
|
471
509
|
ensureButton(id, name, entry) {
|
|
472
510
|
return this.ensureControl(id, name, entry, "button");
|
|
473
511
|
}
|
|
512
|
+
async ensureSelector(id, name, entry, states) {
|
|
513
|
+
if (!this.ensuredFolders.has(id)) {
|
|
514
|
+
await this.ensurePath(id);
|
|
515
|
+
await this.setObjectNotExistsAsync(id, {
|
|
516
|
+
type: "state",
|
|
517
|
+
common: { name, type: "number", role: "value", read: true, write: true, states },
|
|
518
|
+
native: {}
|
|
519
|
+
});
|
|
520
|
+
await this.setStateAsync(id, { val: 0, ack: true });
|
|
521
|
+
this.ensuredFolders.add(id);
|
|
522
|
+
}
|
|
523
|
+
this.registry.set(id, entry);
|
|
524
|
+
}
|
|
525
|
+
async fetchSnapshotB64(oid, snapId) {
|
|
526
|
+
const imgRes = await this.apiGetBuffer(`/photo.jpg?oid=${oid}`);
|
|
527
|
+
if (imgRes.ok && imgRes.data) {
|
|
528
|
+
await this.setStateAsync(snapId, {
|
|
529
|
+
val: `data:image/jpeg;base64,${imgRes.data.toString("base64")}`,
|
|
530
|
+
ack: true
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
}
|
|
474
534
|
async ensureFlag(id, name) {
|
|
475
535
|
if (this.ensuredFolders.has(id)) {
|
|
476
536
|
return;
|
|
@@ -501,6 +561,28 @@ class AgentDvr extends utils.Adapter {
|
|
|
501
561
|
for (const c of SYS_COMMANDS) {
|
|
502
562
|
await this.ensureButton(`system.control.${c.id}`, c.name, { kind: "sys", path: c.path });
|
|
503
563
|
}
|
|
564
|
+
await this.ensureFolder("system.profile", "Profile", "channel");
|
|
565
|
+
await this.ensureSelector(
|
|
566
|
+
"system.profile.selector",
|
|
567
|
+
"Active profile",
|
|
568
|
+
{ kind: "setProfile" },
|
|
569
|
+
{ 0: "Home", 1: "Away", 2: "Night" }
|
|
570
|
+
);
|
|
571
|
+
if (!this.ensuredFolders.has("system.profile.list")) {
|
|
572
|
+
await this.setObjectNotExistsAsync("system.profile.list", {
|
|
573
|
+
type: "state",
|
|
574
|
+
common: {
|
|
575
|
+
name: "Available profiles (JSON)",
|
|
576
|
+
type: "string",
|
|
577
|
+
role: "json",
|
|
578
|
+
read: true,
|
|
579
|
+
write: false
|
|
580
|
+
},
|
|
581
|
+
native: {}
|
|
582
|
+
});
|
|
583
|
+
this.ensuredFolders.add("system.profile.list");
|
|
584
|
+
await this.setStateAsync("system.profile.list", { val: "[]", ack: true });
|
|
585
|
+
}
|
|
504
586
|
}
|
|
505
587
|
}
|
|
506
588
|
// ---- camera aspect detection ----
|
|
@@ -570,6 +652,33 @@ class AgentDvr extends utils.Adapter {
|
|
|
570
652
|
await this.writeLeaf(`${fid}.urls.mjpeg`, `${this.baseUrl}/video.mjpg?oids=${d.oid}`);
|
|
571
653
|
await this.writeLeaf(`${fid}.urls.mp4`, `${this.baseUrl}/video.mp4?oids=${d.oid}`);
|
|
572
654
|
}
|
|
655
|
+
if (d.ot === 2) {
|
|
656
|
+
const snapId = `${fid}.snapshot_b64`;
|
|
657
|
+
if (!this.ensuredFolders.has(snapId)) {
|
|
658
|
+
await this.ensurePath(snapId);
|
|
659
|
+
await this.setObjectNotExistsAsync(snapId, {
|
|
660
|
+
type: "state",
|
|
661
|
+
common: {
|
|
662
|
+
name: "Snapshot (Base64)",
|
|
663
|
+
type: "string",
|
|
664
|
+
role: "media.picture",
|
|
665
|
+
read: true,
|
|
666
|
+
write: false
|
|
667
|
+
},
|
|
668
|
+
native: {}
|
|
669
|
+
});
|
|
670
|
+
await this.setStateAsync(snapId, { val: "", ack: true });
|
|
671
|
+
this.ensuredFolders.add(snapId);
|
|
672
|
+
}
|
|
673
|
+
await this.ensureButton(`${fid}.control.refreshSnapshotB64`, "Refresh snapshot (Base64)", {
|
|
674
|
+
kind: "snapshotB64",
|
|
675
|
+
oid: d.oid,
|
|
676
|
+
fid
|
|
677
|
+
});
|
|
678
|
+
if (this.config.enableSnapshotB64) {
|
|
679
|
+
await this.fetchSnapshotB64(d.oid, snapId);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
573
682
|
await this.updateCameraEvents(d, fid);
|
|
574
683
|
}
|
|
575
684
|
// ---- event formatting ----
|
|
@@ -829,6 +938,7 @@ class AgentDvr extends utils.Adapter {
|
|
|
829
938
|
}
|
|
830
939
|
// ---- main poll ----
|
|
831
940
|
async poll() {
|
|
941
|
+
var _a, _b;
|
|
832
942
|
const res = await this.apiGet("/command/getObjects");
|
|
833
943
|
const json = asJson(res.data);
|
|
834
944
|
if (!res.ok || !json) {
|
|
@@ -864,6 +974,34 @@ class AgentDvr extends utils.Adapter {
|
|
|
864
974
|
if (status) {
|
|
865
975
|
await this.flattenWrite(status, "system.status", 0);
|
|
866
976
|
}
|
|
977
|
+
if (this.config.enableSystemControls && Array.isArray(json.profiles)) {
|
|
978
|
+
const states = {};
|
|
979
|
+
let activeInd = null;
|
|
980
|
+
for (const p of json.profiles) {
|
|
981
|
+
if (p && typeof p === "object") {
|
|
982
|
+
const po = p;
|
|
983
|
+
const ind = (_b = (_a = po.id) != null ? _a : po.ind) != null ? _b : po.index;
|
|
984
|
+
const pname = po.name;
|
|
985
|
+
if (typeof ind === "number" && (typeof pname === "string" || typeof pname === "number")) {
|
|
986
|
+
states[ind] = String(pname);
|
|
987
|
+
if (po.active === true) {
|
|
988
|
+
activeInd = ind;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
if (Object.keys(states).length > 0) {
|
|
994
|
+
const sig = JSON.stringify(states);
|
|
995
|
+
if (sig !== this.profileSig) {
|
|
996
|
+
this.profileSig = sig;
|
|
997
|
+
await this.extendObjectAsync("system.profile.selector", { common: { states } });
|
|
998
|
+
await this.setStateAsync("system.profile.list", { val: sig, ack: true });
|
|
999
|
+
}
|
|
1000
|
+
if (activeInd !== null) {
|
|
1001
|
+
await this.setStateAsync("system.profile.selector", { val: activeInd, ack: true });
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
867
1005
|
if (this.config.enableOverview) {
|
|
868
1006
|
const cams = devices.filter((d) => d.ot === 2);
|
|
869
1007
|
const ovId = "overview";
|
|
@@ -931,6 +1069,27 @@ class AgentDvr extends utils.Adapter {
|
|
|
931
1069
|
}
|
|
932
1070
|
}
|
|
933
1071
|
async runCommand(relId, entry, val) {
|
|
1072
|
+
if (entry.kind === "setProfile") {
|
|
1073
|
+
const ind = typeof val === "number" ? val : parseInt(String(val != null ? val : ""), 10);
|
|
1074
|
+
if (!isNaN(ind)) {
|
|
1075
|
+
const url2 = `/command/setProfile?ind=${ind}`;
|
|
1076
|
+
const cmdRes2 = await this.apiGet(url2);
|
|
1077
|
+
if (cmdRes2.ok) {
|
|
1078
|
+
this.log.debug(`OK: ${url2}`);
|
|
1079
|
+
await this.setStateAsync(relId, { val: ind, ack: true });
|
|
1080
|
+
} else {
|
|
1081
|
+
this.log.warn(`Command failed (${url2}): ${cmdRes2.error}`);
|
|
1082
|
+
}
|
|
1083
|
+
this.scheduleRefresh();
|
|
1084
|
+
}
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1087
|
+
if (entry.kind === "snapshotB64") {
|
|
1088
|
+
const snapId = `${entry.fid}.snapshot_b64`;
|
|
1089
|
+
await this.fetchSnapshotB64(entry.oid, snapId);
|
|
1090
|
+
await this.setStateAsync(relId, { val: false, ack: true });
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
934
1093
|
if (entry.kind === "push") {
|
|
935
1094
|
this.log.info(`Push trigger cam ${entry.oid}`);
|
|
936
1095
|
await this.setStateAsync(relId, { val: "", ack: true });
|