node-red-contrib-hik-media-buffer 1.2.1 → 1.2.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/hik-snapshot.html +4 -4
- package/hik-snapshot.js +27 -14
- package/package.json +1 -1
package/hik-snapshot.html
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
color: '#00b4d8',
|
|
5
5
|
defaults: {
|
|
6
6
|
name: { value: "" },
|
|
7
|
-
host: { value: ""
|
|
8
|
-
channel: {value: ""
|
|
7
|
+
host: { value: ""},
|
|
8
|
+
channel: {value: ""},
|
|
9
9
|
protocol: { value: "http" },
|
|
10
|
-
port: { value: "80"
|
|
11
|
-
user: { value: "admin"
|
|
10
|
+
port: { value: "80"},
|
|
11
|
+
user: { value: "admin"},
|
|
12
12
|
pass: { value: "" },
|
|
13
13
|
|
|
14
14
|
},
|
package/hik-snapshot.js
CHANGED
|
@@ -8,9 +8,8 @@ module.exports = function(RED) {
|
|
|
8
8
|
RED.nodes.createNode(this, config);
|
|
9
9
|
const node = this;
|
|
10
10
|
|
|
11
|
-
//
|
|
11
|
+
// Parametri di default salvati dalla configurazione grafica del nodo
|
|
12
12
|
node.nodeName = config.name || `NVR_${config.host}`;
|
|
13
|
-
|
|
14
13
|
node.protocol = config.protocol || "http";
|
|
15
14
|
node.host = config.host;
|
|
16
15
|
node.port = config.port || "80";
|
|
@@ -21,13 +20,25 @@ module.exports = function(RED) {
|
|
|
21
20
|
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
|
22
21
|
|
|
23
22
|
node.on('input', async function(msg) {
|
|
24
|
-
|
|
23
|
+
// 🌟 1. LOGICA DI ACCETTAZIONE FLESSIBILE
|
|
24
|
+
// Il nodo parte se il payload è 'true' OPPURE se stiamo passando una configurazione dinamica
|
|
25
|
+
if (msg.payload !== true && typeof msg.payload !== 'object') return;
|
|
25
26
|
|
|
26
27
|
node.status({fill: "blue", shape: "dot", text: "Verifica canali..."});
|
|
27
28
|
|
|
29
|
+
// 🌟 2. VALUTAZIONE PARAMETRI DINAMICI VS PARAMETRI STATICI
|
|
30
|
+
// Se le proprietà sono presenti nel msg, usiamo quelle, altrimenti facciamo il fallback su quelle del nodo
|
|
31
|
+
const NVR_HOST = msg.nvr_host || node.host;
|
|
32
|
+
const NVR_PORT = msg.nvr_port || node.port;
|
|
33
|
+
const NVR_USER = msg.nvr_user || node.user;
|
|
34
|
+
const NVR_PASS = msg.nvr_pass || node.pass;
|
|
35
|
+
const NVR_NAME = msg.nvr_name || node.nodeName;
|
|
36
|
+
const MAX_CHANNELS = parseInt(msg.nvr_channels) || node.maxChannels;
|
|
37
|
+
const PROTOCOL = msg.nvr_protocol || node.protocol;
|
|
38
|
+
|
|
28
39
|
const digest = new DigestAuthClass({
|
|
29
|
-
username:
|
|
30
|
-
password:
|
|
40
|
+
username: NVR_USER,
|
|
41
|
+
password: NVR_PASS
|
|
31
42
|
});
|
|
32
43
|
|
|
33
44
|
const data = new Date();
|
|
@@ -37,15 +48,16 @@ module.exports = function(RED) {
|
|
|
37
48
|
|
|
38
49
|
let snapshotResults = [];
|
|
39
50
|
|
|
40
|
-
|
|
51
|
+
// Il ciclo ora scala dinamicamente in base al numero di canali calcolato
|
|
52
|
+
for (let i = 1; i <= MAX_CHANNELS; i++) {
|
|
41
53
|
const chanId = i + "01";
|
|
42
|
-
const snapUrl = `${
|
|
43
|
-
const recordUrl = `${
|
|
54
|
+
const snapUrl = `${PROTOCOL}://${NVR_HOST}:${NVR_PORT}/ISAPI/Streaming/channels/${chanId}/picture`;
|
|
55
|
+
const recordUrl = `${PROTOCOL}://${NVR_HOST}:${NVR_PORT}/ISAPI/ContentMgmt/record/tracks/${chanId}/dailyDistribution`;
|
|
44
56
|
|
|
45
57
|
const recordXml = `<?xml version="1.0" encoding="utf-8"?><trackDailyParam><year>${year}</year><monthOfYear>${month}</monthOfYear><dayOfMonth>${day}</dayOfMonth></trackDailyParam>`;
|
|
46
58
|
|
|
47
59
|
let resCanale = {
|
|
48
|
-
name:
|
|
60
|
+
name: NVR_NAME, // Dinamico o statico a seconda della modalità
|
|
49
61
|
channel: i,
|
|
50
62
|
photo: null,
|
|
51
63
|
snapOk: false,
|
|
@@ -58,7 +70,7 @@ module.exports = function(RED) {
|
|
|
58
70
|
method: 'GET',
|
|
59
71
|
url: snapUrl,
|
|
60
72
|
responseType: 'arraybuffer',
|
|
61
|
-
httpsAgent:
|
|
73
|
+
httpsAgent: PROTOCOL === 'https' ? httpsAgent : undefined,
|
|
62
74
|
timeout: 5000
|
|
63
75
|
});
|
|
64
76
|
resCanale.photo = responseSnap.data;
|
|
@@ -74,7 +86,7 @@ module.exports = function(RED) {
|
|
|
74
86
|
url: recordUrl,
|
|
75
87
|
data: recordXml,
|
|
76
88
|
headers: { 'Content-Type': 'application/xml' },
|
|
77
|
-
httpsAgent:
|
|
89
|
+
httpsAgent: PROTOCOL === 'https' ? httpsAgent : undefined,
|
|
78
90
|
timeout: 5000
|
|
79
91
|
});
|
|
80
92
|
const xmlOutput = responseRec.data.toString();
|
|
@@ -88,17 +100,18 @@ module.exports = function(RED) {
|
|
|
88
100
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
89
101
|
}
|
|
90
102
|
|
|
103
|
+
// Restituiamo i risultati sovrascrivendo il payload ma lasciando inalterato il resto del msg (es. msg.chatId)
|
|
91
104
|
msg.payload = snapshotResults;
|
|
92
105
|
node.send(msg);
|
|
93
106
|
|
|
94
|
-
// Conteggi per lo stato del nodo
|
|
107
|
+
// Conteggi per lo stato visivo sul quadratino del nodo
|
|
95
108
|
const snapCount = snapshotResults.filter(v => v.snapOk).length;
|
|
96
109
|
const recCount = snapshotResults.filter(v => v.isRecording).length;
|
|
97
110
|
|
|
98
111
|
node.status({
|
|
99
|
-
fill: (snapCount ===
|
|
112
|
+
fill: (snapCount === MAX_CHANNELS && recCount === MAX_CHANNELS) ? "green" : "yellow",
|
|
100
113
|
shape: "dot",
|
|
101
|
-
text: `Snap: ${snapCount}/${
|
|
114
|
+
text: `Snap: ${snapCount}/${MAX_CHANNELS} | Rec: ${recCount}/${MAX_CHANNELS}`
|
|
102
115
|
});
|
|
103
116
|
});
|
|
104
117
|
}
|