Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-red-contrib-hikvision-ultimate

Package Overview
Dependencies
Maintainers
1
Versions
119
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-red-contrib-hikvision-ultimate - npm Package Compare versions

Comparing version 0.0.13 to 0.0.15

nodes/icons/node-anpr-icon.png

10

CHANGELOG.md

@@ -5,2 +5,12 @@ # node-red-contrib-hikvision-ultimate

<p>
<b>Version 0.0.15 BETA</b> December 2020<br/>
- Moved RAW node code into async functions.<br/>
- Fixed BUG in ANPR module, where the last plate was sent every second..<br/>
- Added icons.<br/>
</p>
<p>
<b>Version 0.0.14 BETA</b> December 2020<br/>
- Moved ANPR code into async functions, do help very slow PC's to correctly handle the data.<br/>
</p>
<p>
<b>Version 0.0.13 BETA</b> December 2020<br/>

@@ -7,0 +17,0 @@ - Moved ANPR code into async functions, do help very slow PC's to correctly handle the data.<br/>

2

nodes/ANPR-config.js

@@ -182,2 +182,4 @@

})
// Set the last plate found, to avoid repeating.
node.lastPicName = oPlates.Plates.Plate[oPlates.Plates.Plate.length - 1].picName;
} else {

@@ -184,0 +186,0 @@ // No new plates found

151

nodes/Hikvision-config.js

@@ -8,2 +8,3 @@

const xml2js = require('xml2js').Parser({ explicitArray: false }).parseString;
const util = require('util');

@@ -28,3 +29,3 @@ function Hikvisionconfig(config) {

// This function starts the heartbeat timer, to detect the disconnection from the server
node.startHeartBeatTimer = () => {
node.resetHeartBeatTimer = () => {
// Reset node.timerCheckHeartBeat

@@ -44,9 +45,14 @@ if (node.timerCheckHeartBeat !== null) clearTimeout(node.timerCheckHeartBeat);

node.isConnected = false;
setTimeout(node.startAlarmStream, 5000); // Reconnect
setTimeout(startAlarmStream, 5000); // Reconnect
}, 25000);
}
node.startAlarmStream = () => {
async function startAlarmStream() {
node.resetHeartBeatTimer(); // First thing, start the heartbeat timer.
node.setAllClientsStatus({ fill: "grey", shape: "ring", text: "Connecting..." });
const client = new DigestFetch(node.credentials.user, node.credentials.password); // Instantiate the fetch client.
controller = new AbortController(); // For aborting the stream request
var client = new DigestFetch(node.credentials.user, node.credentials.password); // Instantiate the fetch client.
var options = {

@@ -63,81 +69,91 @@ // These properties are part of the Fetch Standard

timeout: 0, // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies). Signal is recommended instead.
compress: true, // support gzip/deflate content encoding. false to disable
compress: false, // support gzip/deflate content encoding. false to disable
size: 0, // maximum response body size in bytes. 0 to disable
agent: null // http(s).Agent instance or function that returns an instance (see below)
}
node.startHeartBeatTimer(); // First thing, start the heartbeat timer.
node.setAllClientsStatus({ fill: "grey", shape: "ring", text: "Connecting..." });
};
try {
client.fetch("http://" + node.host + "/ISAPI/Event/notification/alertStream", options)
.then(response => {
//console.log(response.status + " " + response.statusText);
if (response.statusText === "Unauthorized") {
node.setAllClientsStatus({ fill: "red", shape: "ring", text: response.statusText });
}
if (response.statusText === "Ok") {
node.setAllClientsStatus({ fill: "green", shape: "ring", text: "Connected. Waiting for Alarm." });
}
return response.body;
})
.then(body => {
body.on('readable', () => {
node.isConnected = true;
try {
let chunk;
var sRet = ""
while (null !== (chunk = body.read())) {
sRet = chunk.toString();
}
//console.log("BANANA " + sRet)
sRet = sRet.replace(/--boundary/g, '');
var i = sRet.indexOf("<"); // Get only the XML, starting with "<"
if (i > -1) {
sRet = sRet.substring(i);
// console.log("BANANA SBANANATO " + sRet);
// By xml2js
xml2js(sRet, function (err, result) {
node.nodeClients.forEach(oClient => {
if (result !== undefined) oClient.sendPayload({ topic: oClient.topic || "", payload: result.EventNotificationAlert, connected: true });
})
});
} else {
i = sRet.indexOf("{") // It's a Json
// Async get the body, called by streamPipeline(response.body, readStream);
// ###################################
const streamPipeline = util.promisify(require('stream').pipeline);
async function readStream(stream) {
try {
for await (const chunk of stream) {
var sRet = "";
sRet = chunk.toString();
// // console.log("BANANA " + sRet);
try {
sRet = sRet.replace(/--boundary/g, '');
var i = sRet.indexOf("<"); // Get only the XML, starting with "<"
if (i > -1) {
sRet = sRet.substring(i);
//sRet = sRet.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '); // Fix numbers and chars invalid in JSON
//console.log("BANANA : " + sRet);
node.nodeClients.forEach(oClient => {
oClient.sendPayload({ topic: oClient.topic || "", payload: JSON.parse(sRet), connected: true });
})
// // // console.log("BANANA SBANANATO " + sRet);
// By xml2js
xml2js(sRet, function (err, result) {
node.nodeClients.forEach(oClient => {
if (result !== undefined) oClient.sendPayload({ topic: oClient.topic || "", payload: result.EventNotificationAlert, connected: true });
})
});
} else {
// Invalid body
RED.log.info("Hikvision-config: DecodingBody: Invalid Json " + sRet);
i = sRet.indexOf("{") // It's a Json
if (i > -1) {
sRet = sRet.substring(i);
//sRet = sRet.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '); // Fix numbers and chars invalid in JSON
// // console.log("BANANA JSONATO: " + sRet);
node.nodeClients.forEach(oClient => {
oClient.sendPayload({ topic: oClient.topic || "", payload: JSON.parse(sRet), connected: true });
})
} else {
// Invalid body
RED.log.info("Hikvision-config: DecodingBody: Invalid Json " + sRet);
}
}
// All is fine. Reset and restart the hearbeat timer
// Hikvision sends an heartbeat alarm (videoloss), depending on firmware, every 300ms or more.
// If this HeartBeat isn't received, abort the stream request and restart.
node.resetHeartBeatTimer();
} catch (error) {
// // console.log("BANANA startAlarmStream decodifica body: " + error);
RED.log.info("Hikvision-config: DecodingBody error: " + error);
}
}
} catch (error) {
// // console.log("BANANA NEL BODY errore " + error);
return;
}
}
// ###################################
} catch (error) { RED.log.error("Hikvision-config: ERRORE CATCHATO " + error); }
// All is fine. Reset and restart the hearbeat timer
// Hikvision sends an heartbeat alarm (videoloss), depending on firmware, every 300ms or more.
// If this HeartBeat isn't received, abort the stream request and restart.
node.startHeartBeatTimer();
});
})
.catch(err => {
node.setAllClientsStatus({ fill: "grey", shape: "ring", text: "Server unreachable: " + err + " Retry..." });
if (node.isConnected) {
const response = await client.fetch("http://" + node.host + "/ISAPI/Event/notification/alertStream", options);
if (response.status >= 200 && response.status <= 300) {
node.setAllClientsStatus({ fill: "green", shape: "ring", text: "Connected. Waiting for Alarm." });
} else {
node.setAllClientsStatus({ fill: "red", shape: "ring", text: response.statusText });
// // console.log("BANANA Error response " + response.statusText);
throw ("Error response: " + response.statusText);
}
node.isConnected = true;
streamPipeline(response.body, readStream);
} catch (err) {
// Main Error
// // console.log("BANANA MAIN ERROR: " + err);
// Abort request
try {
if (controller !== null) controller.abort();
} catch (error) { }
node.setAllClientsStatus({ fill: "grey", shape: "ring", text: "Server unreachable: " + err + " Retry..." });
if (node.isConnected) {
try {
node.nodeClients.forEach(oClient => {
oClient.sendPayload({ topic: oClient.topic || "", payload: null, connected: false });
})
}
node.isConnected = false;
return;
});
} catch (error) { }
}
node.isConnected = false;
};
};
setTimeout(node.startAlarmStream, 5000); // First connection.
setTimeout(startAlarmStream, 5000); // First connection.

@@ -151,3 +167,2 @@

if (node.timerCheckHeartBeat !== null) clearTimeout(node.timerCheckHeartBeat);
if (node.startAlarmStream !== null) clearTimeout(node.startAlarmStream)
done();

@@ -154,0 +169,0 @@ });

{
"name": "node-red-contrib-hikvision-ultimate",
"version": "0.0.13",
"version": "0.0.15",
"description": "A native set of node for Hikvision Cameras, Alarms, Radars etc.",

@@ -10,3 +10,4 @@ "author": "Supergiovane (https://github.com/Supergiovane)",

"digest-fetch": "1.1.5",
"abort-controller": ">=3.0.0"
"abort-controller": ">=3.0.0",
"util": ">=0.12.3"
},

@@ -35,2 +36,2 @@ "keywords": [

}
}
}

@@ -21,3 +21,3 @@ # node-red-contrib-hikvision-ultimate

***THIS NODESET IS IN BETA. E' ancora brutto, ma funziona.***<br/>
***THIS NODE IS IN BETA***<br/>
I'll add helps, docs and samples in this README page. Please have some patience...<br/>

@@ -30,3 +30,2 @@

<br/>
<br/>

@@ -33,0 +32,0 @@ ## - RAW Alarm Node

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc