node-red-contrib-hik-media-buffer 1.1.47 → 1.1.49

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 +24 -18
  2. package/package.json +1 -1
@@ -22,9 +22,7 @@ module.exports = function(RED) {
22
22
  let isClosing = false;
23
23
  let lastTriggerTime = {};
24
24
  let nvrOnline = true;
25
-
26
25
  let statoCanale = {};
27
- let ultimoAllarmeTempo = {};
28
26
 
29
27
  const httpsAgent = new https.Agent({ rejectUnauthorized: false });
30
28
 
@@ -80,6 +78,7 @@ module.exports = function(RED) {
80
78
  while ((matchBlocco = bloccoRegex.exec(xmlData)) !== null) {
81
79
  const bloccoContenuto = matchBlocco[1];
82
80
 
81
+ // FISSO: Corretto il nome della variabile bloccoContenuto (prima c'era un typo che rompeva il nodo)
83
82
  const idMatch = bloccoContenuto.match(/<id>(\d+)<\/id>/i);
84
83
  const statusMatch = bloccoContenuto.match(/<status>([^<]+)</i);
85
84
 
@@ -120,20 +119,20 @@ module.exports = function(RED) {
120
119
 
121
120
  const heartbeatInterval = setInterval(checkCameras, 30000);
122
121
 
123
- // --- DOWNLOAD MULTIMEDIALE DA NVR CON LOGICA STRUTTURALE ORIGINALE ---
122
+ // --- DOWNLOAD MULTIMEDIALE BASATO SULL'ISPEZIONA REALE DELL'NVR ---
124
123
  async function downloadMedia(evento, channelID) {
125
124
  const nowTime = Date.now();
126
125
  if (!lastTriggerTime[channelID]) lastTriggerTime[channelID] = 0;
127
126
  if (nowTime - lastTriggerTime[channelID] < 5000) return;
128
127
  lastTriggerTime[channelID] = nowTime;
129
128
 
130
- // ISTANZIAMO camAuth SULL'NVR: Risolve il problema delle credenziali vuote nel vecchio blocco
131
129
  const camAuth = new AxiosDigestAuth({ username: node.user, password: node.pass });
132
130
 
133
131
  const referenceTime = new Date();
134
132
  const timestamp = Math.floor(referenceTime.getTime() / 1000);
135
- const startTime = toHikDate(new Date(referenceTime.getTime() - (10 * 1000)));
136
- const endTime = toHikDate(new Date(referenceTime.getTime() + (10 * 1000)));
133
+
134
+ const startTime = toHikDate(new Date(referenceTime.getTime() - (20 * 1000)));
135
+ const endTime = toHikDate(new Date(referenceTime.getTime() + (20 * 1000)));
137
136
 
138
137
  node.status({fill:"yellow", shape:"dot", text:`Download Cam ${channelID}...`});
139
138
  const nomeCamera = await getCameraName(channelID);
@@ -141,12 +140,20 @@ module.exports = function(RED) {
141
140
  await new Promise(resolve => setTimeout(resolve, 6000));
142
141
  const baseUrl = `${node.protocol}://${node.host}:${node.port}/ISAPI/ContentMgmt`;
143
142
 
143
+ let eventoNVR = "FieldDetection";
144
+ for (let e of EventList) {
145
+ if (evento.toLowerCase() === e.toLowerCase()) {
146
+ eventoNVR = e;
147
+ break;
148
+ }
149
+ }
150
+
144
151
  let output = {
145
152
  tipo_messaggio: "evento",
146
153
  nome_cliente: node.name,
147
154
  nome_telecamera: nomeCamera,
148
155
  ip_telecamera: node.host,
149
- tipo_evento: evento,
156
+ tipo_evento: eventoNVR,
150
157
  timestamp_epoch: timestamp,
151
158
  stato_telecamera: "ONLINE",
152
159
  channel: channelID.toString(),
@@ -155,16 +162,19 @@ module.exports = function(RED) {
155
162
  };
156
163
 
157
164
  const parsedChannel = parseInt(channelID, 10);
158
- const trackVideo = (parsedChannel * 100) + 1; // Formula NVR (*100+1)
159
- const trackFoto = (parsedChannel * 100) + 3; // Formula NVR (*100+3)
165
+ const trackVideo = (parsedChannel * 100) + 1; // Canale 2 -> 201
166
+ const trackFoto = (parsedChannel * 100) + 3; // Canale 2 -> 203
160
167
 
161
- const tracks = [{ id: trackVideo.toString() }, { id: trackFoto.toString() }];
168
+ const tracks = [
169
+ { id: trackVideo.toString(), isFoto: false },
170
+ { id: trackFoto.toString(), isFoto: true }
171
+ ];
162
172
  let fileDaCancellare = [];
163
173
 
164
174
  try {
165
175
  for (let t of tracks) {
166
- // RIPRISTINATO: Il tuo XML originale esatto con <trackIDList> e ${evento} dinamico
167
- 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.toLowerCase()}</metadataDescriptor></metadataList></CMSearchDescription>`;
176
+ // FISSO: Logica XML clonata al 100% dal tuo ispeziona NVR reale
177
+ 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><contentTypeList><contentType>metadata</contentType></contentTypeList><maxResults>30</maxResults><metadataList><metadataDescriptor>recordType.meta.hikvision.com/${eventoNVR}</metadataDescriptor></metadataList></CMSearchDescription>`;
168
178
 
169
179
  const resSearch = await camAuth.request({
170
180
  method: 'POST', url: `${baseUrl}/search`, data: searchXml, headers: { "Content-Type": "application/xml" }
@@ -183,14 +193,12 @@ module.exports = function(RED) {
183
193
  });
184
194
 
185
195
  let buffer = Buffer.from(resDown.data);
186
- if (t.id === trackFoto.toString()) {
187
- // SALVA FOTO IN LOCALE
196
+ if (t.isFoto) {
188
197
  const fullImgPath = path.join(baseStorage, `img_${timestamp}.jpg`);
189
198
  fs.writeFileSync(fullImgPath, buffer);
190
199
  output.foto_base64 = fs.readFileSync(fullImgPath, { encoding: 'base64' });
191
200
  fileDaCancellare.push(fullImgPath);
192
201
  } else {
193
- // SALVA VIDEO IN LOCALE
194
202
  if (buffer.slice(0, 4).toString() === 'IMKH') buffer = buffer.slice(40);
195
203
  const rawPath = path.join(baseStorage, `raw_${timestamp}.mp4`);
196
204
  const fixedPath = path.join(baseStorage, `hik_v_${channelID}_${timestamp}.mp4`);
@@ -245,9 +253,7 @@ module.exports = function(RED) {
245
253
  if (chMatch) {
246
254
  let ev = "Unknown";
247
255
  for (let e of EventList) { if (data.includes(e.toLowerCase())) { ev = e; break; } }
248
-
249
- if (ev === "Unknown") return; // Ignora heartbeat o altri eventi non mappati
250
-
256
+ if (ev === "Unknown") return;
251
257
  downloadMedia(ev, chMatch[1]);
252
258
  }
253
259
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-hik-media-buffer",
3
- "version": "1.1.47",
3
+ "version": "1.1.49",
4
4
  "description": "Ottiene buffer video e immagine da camere Hikvision via ISAPI",
5
5
  "keywords": [
6
6
  "node-red",