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 CHANGED
@@ -4,11 +4,11 @@
4
4
  color: '#00b4d8',
5
5
  defaults: {
6
6
  name: { value: "" },
7
- host: { value: "", required: true },
8
- channel: {value: "", required: true},
7
+ host: { value: ""},
8
+ channel: {value: ""},
9
9
  protocol: { value: "http" },
10
- port: { value: "80", required: true },
11
- user: { value: "admin", required: true },
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
- // Recuperiamo il nome del nodo dalla configurazione (se vuoto usa l'host)
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
- if (msg.payload !== true) return;
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: node.user,
30
- password: node.pass
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
- for (let i = 1; i <= node.maxChannels; i++) {
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 = `${node.protocol}://${node.host}:${node.port}/ISAPI/Streaming/channels/${chanId}/picture`;
43
- const recordUrl = `${node.protocol}://${node.host}:${node.port}/ISAPI/ContentMgmt/record/tracks/${chanId}/dailyDistribution`;
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: node.nodeName, // <--- INIEZIONE RIGIDA DEL NOME DEL CONDOMINIO
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: node.protocol === 'https' ? httpsAgent : undefined,
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: node.protocol === 'https' ? httpsAgent : undefined,
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 === node.maxChannels && recCount === node.maxChannels) ? "green" : "yellow",
112
+ fill: (snapCount === MAX_CHANNELS && recCount === MAX_CHANNELS) ? "green" : "yellow",
100
113
  shape: "dot",
101
- text: `Snap: ${snapCount}/${node.maxChannels} | Rec: ${recCount}/${node.maxChannels}`
114
+ text: `Snap: ${snapCount}/${MAX_CHANNELS} | Rec: ${recCount}/${MAX_CHANNELS}`
102
115
  });
103
116
  });
104
117
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-hik-media-buffer",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "Ottiene buffer video e immagine da camere Hikvision via ISAPI",
5
5
  "keywords": [
6
6
  "node-red",