node-red-contrib-hik-media-buffer 1.1.43 → 1.1.45

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.
Files changed (2) hide show
  1. package/hik-media-buffer.js +17 -12
  2. package/package.json +1 -1
@@ -65,7 +65,7 @@ module.exports = function(RED) {
65
65
  const nvrAuth = new AxiosDigestAuth({ username: node.user, password: node.pass });
66
66
 
67
67
  try {
68
- // Interroghiamo l'NVR sullo stato globale dei suoi canali proxy [ps. 57-58 del manuale]
68
+ // Interroghiamo l'NVR sullo stato globale dei suoi canali proxy
69
69
  const res = await nvrAuth.request({
70
70
  method: 'GET',
71
71
  url: `${node.protocol}://${node.host}:${node.port}/ISAPI/ContentMgmt/InputProxy/channels/status`,
@@ -85,7 +85,7 @@ module.exports = function(RED) {
85
85
 
86
86
  // Estraiamo l'ID del canale e il suo stato dal blocco attuale
87
87
  const idMatch = bloccoContenuto.match(/<id>(\d+)<\/id>/i);
88
- const statusMatch = bloccoContenuto.match(/<status>([^<]+)<\/status>/i);
88
+ const statusMatch = bloccoContenuto.match(/<status>([^<]+)</i); // Corretta regex di chiusura tag
89
89
 
90
90
  if (idMatch && statusMatch) {
91
91
  const ch = idMatch[1];
@@ -102,7 +102,7 @@ module.exports = function(RED) {
102
102
  node.send({ payload: { tipo_messaggio: "status", stato_telecamera: "offline", nome_cliente: node.name, nome_telecamera: `Canale_${ch}`, ip_nvr: node.host, channel: ch.toString(), msg: "Camera scollegata o offline su NVR" } });
103
103
  statoCanale[ch] = false;
104
104
  } else if (statoCanale[ch] === undefined) {
105
- // Primo avvio: memorizziamo lo stato iniziale senza inviare messaggi di stato a vuoto
105
+ // Primo avvio: memorizziamo lo stato iniziale
106
106
  statoCanale[ch] = isOnline;
107
107
  }
108
108
  }
@@ -124,7 +124,6 @@ module.exports = function(RED) {
124
124
  }
125
125
  }
126
126
 
127
- // Il controllo camere gira in background ogni 30 secondi interrogando solo l'NVR
128
127
  const heartbeatInterval = setInterval(checkCameras, 30000);
129
128
 
130
129
  // --- DOWNLOAD, SALVATAGGIO, CONVERSIONE E RIMOZIONE DALL'NVR ---
@@ -137,12 +136,13 @@ module.exports = function(RED) {
137
136
  const nvrAuth = new AxiosDigestAuth({ username: node.user, password: node.pass });
138
137
  const referenceTime = new Date();
139
138
  const timestamp = Math.floor(referenceTime.getTime() / 1000);
140
- const startTime = toHikDate(new Date(referenceTime.getTime() - (10 * 1000)));
141
- const endTime = toHikDate(new Date(referenceTime.getTime() + (10 * 1000)));
139
+ const startTime = toHikDate(new Date(referenceTime.getTime() - (15 * 1000))); // Allargato a 15s per sicurezza
140
+ const endTime = toHikDate(new Date(referenceTime.getTime() + (15 * 1000)));
142
141
 
143
142
  node.status({fill:"yellow", shape:"dot", text:`Download Cam ${channelID}...`});
144
143
  const nomeCamera = await getCameraName(channelID);
145
144
 
145
+ // Ritardo tecnico per dare tempo all'NVR di chiudere e indicizzare il file su HDD
146
146
  await new Promise(resolve => setTimeout(resolve, 6000));
147
147
  const baseUrl = `${node.protocol}://${node.host}:${node.port}/ISAPI/ContentMgmt`;
148
148
 
@@ -161,15 +161,14 @@ module.exports = function(RED) {
161
161
 
162
162
  let fileDaCancellare = [];
163
163
  const parsedChannel = parseInt(channelID, 10);
164
- const trackVideo = (parsedChannel * 100) + 1; // Formula dinamica NVR (*100+1) [cite: 958]
165
- const trackFoto = (parsedChannel * 100) + 3; // Formula dinamica NVR (*100+3) [cite: 958]
164
+ const trackVideo = (parsedChannel * 100) + 1; // Formula dinamica NVR (*100+1) e.g. 201
165
+ const trackFoto = (parsedChannel * 100) + 3; // Formula dinamica NVR (*100+3) e.g. 203
166
166
 
167
167
  const tracks = [{ id: trackVideo.toString(), type: "video" }, { id: trackFoto.toString(), type: "foto" }];
168
168
 
169
169
  try {
170
170
  for (let t of tracks) {
171
171
  const searchXml = `<?xml version="1.0" encoding="utf-8"?><CMSearchDescription><searchID>LAST_EVENT</searchID><trackIDList><trackID>${t.id}</trackID></trackIDList><timeSpanList><timeSpan><startTime>${startTime}</startTime><endTime>${endTime}</endTime></timeSpan></timeSpanList><maxResults>100</maxResults><metadataList><metadataDescriptor>//recordType.meta.std-cgi.com/${evento}</metadataDescriptor></metadataList></CMSearchDescription>`;
172
-
173
172
  const resSearch = await nvrAuth.request({
174
173
  method: 'POST', url: `${baseUrl}/search`, data: searchXml, headers: { "Content-Type": "application/xml" }
175
174
  });
@@ -179,7 +178,7 @@ module.exports = function(RED) {
179
178
 
180
179
  if (uriMatch) {
181
180
  const rawUri = uriMatch[1].replace(/&amp;/g, '&');
182
- const resDown = await camAuth.request({
181
+ const resDown = await nvrAuth.request({
183
182
  method: 'GET',
184
183
  url: `${baseUrl}/download`,
185
184
  data: `<?xml version="1.0" encoding="UTF-8"?><downloadRequest><playbackURI>${rawUri.replace(/&/g, '&amp;')}</playbackURI></downloadRequest>`,
@@ -225,7 +224,7 @@ module.exports = function(RED) {
225
224
  }
226
225
 
227
226
  } catch (e) {
228
- node.error(`Errore Download Cam ${channelID}: ${e.message}`);
227
+ node.error(`Errore Download NVR per Canale ${channelID}: ${e.message}`);
229
228
  }
230
229
  node.status({fill:"green", shape:"ring", text:"In ascolto"});
231
230
  }
@@ -248,14 +247,20 @@ module.exports = function(RED) {
248
247
  if (data.includes("active")) {
249
248
  const chMatch = data.match(/<channelid>(\d+)<\/channelid>/i);
250
249
  if (chMatch) {
250
+ let channelID = chMatch[1];
251
251
  let ev = "Unknown";
252
+
252
253
  for (let e of EventList) {
253
254
  if (data.includes(e.toLowerCase())) {
254
255
  ev = e;
255
256
  break;
256
257
  }
257
258
  }
258
- downloadMedia(ev, chMatch[1]);
259
+
260
+ // Se non è un allarme presente in lista o è un heartbeat, fermati qui
261
+ if (ev === "Unknown") return;
262
+
263
+ downloadMedia(ev, channelID);
259
264
  }
260
265
  }
261
266
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-hik-media-buffer",
3
- "version": "1.1.43",
3
+ "version": "1.1.45",
4
4
  "description": "Ottiene buffer video e immagine da camere Hikvision via ISAPI",
5
5
  "keywords": [
6
6
  "node-red",