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 1.1.18 to 1.1.19

img/speaker.jpg

8

CHANGELOG.md

@@ -7,2 +7,10 @@ <p align="center"><img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/logo.png' width="40%"></p>

<p>
<b>Version 1.1.19</b> April 2024<br/>
- NEW: Speaker node.<br/>
</p>
<p>
<b>Version 1.1.18</b> April 2024<br/>
- ANPR: fixed an issue it the plate's list parser in cameras having ISAPI protocol 1.0.<br/>
</p>
<p>
<b>Version 1.1.17</b> April 2024<br/>

@@ -9,0 +17,0 @@ - ANPR: fixed an issue it the plate's list parser. Thanks @jpgnz.<br/>

34

nodes/hikvisionUltimateSpeaker.js

@@ -9,7 +9,4 @@

node.server = RED.nodes.getNode(config.server)
node.avoidsameplatetime = config.avoidsameplatetime || 20; // Doesn't send the same plate in this timeframe, in seconds.
node.currentPlate = ""; // Stores the current plate (for the avoidsameplatetime function)
node.timerAvoidSamePlate = null; // Timer for avoiding repeating plate
node.bAvoidSamePlate = false;
node.setNodeStatus = ({ fill, shape, text }) => {

@@ -27,19 +24,3 @@ var dDate = new Date();

if (node.currentPlate === _msg.payload) {
if (node.bAvoidSamePlate) {
try { node.setNodeStatus({ fill: "grey", shape: "ring", text: "Temporary block same plate " + _msg.payload }); } catch (error) { };
return;
}
}
// Timer for avoiding same plate
// ##########################
if (node.timerAvoidSamePlate !== null) clearTimeout(node.timerAvoidSamePlate);
node.bAvoidSamePlate = true;
node.timerAvoidSamePlate = setTimeout(() => {
node.bAvoidSamePlate = false;
}, node.avoidsameplatetime * 1000);
// ##########################
node.currentPlate = _msg.payload;
node.send([_msg, null]);

@@ -58,3 +39,14 @@ try {

this.on('input', function (msg) {
if (msg.payload === true) {
(async () => {
msg.payload = await node.server.playAloud(config.customAudioID, config.volume);
node.send([msg, null])
})();
}
if (msg.payload === false) {
(async () => {
msg.payload = await node.server.stopFile(config.customAudioID);
node.send([msg, null])
})();
}
});

@@ -61,0 +53,0 @@

@@ -12,3 +12,3 @@

RED.nodes.createNode(this, config)
var node = this
var node = this;
node.port = config.port || 80;

@@ -23,3 +23,2 @@ node.debug = config.host.toString().toLowerCase().indexOf("banana") > -1;

node.deviceinfo = config.deviceinfo || {};
node.timerCheckRing = null;
var oReadable = new readableStr();

@@ -131,4 +130,4 @@ var controller = null; // AbortController

const resInfo = await clientInfo.fetch(jParams.protocol + "://" + jParams.host + "/ISAPI/AccessControl/EventCardLinkageCfg/CustomAudio?format=json", opt);
const body = await resInfo.text();
res.json(body);
const body = await resInfo.json();
res.json(body.CustomAudioInfoList);
return;

@@ -139,3 +138,55 @@ } catch (error) {

}
})();
} catch (err) {
res.json(err);
}
});
// 17/94/2024 Get the files
RED.httpAdmin.get("/hikvisionUltimateSpeakerTest", RED.auth.needsPermission('Speakerconfig.read'), function (req, res) {
var jParams = RED.nodes.getNode(req.query.nodeID).server;// Retrieve node.id of the config node.
let customAudioID = req.query.customAudioID;
var _nodeServer = null;
var clientInfo;
if (jParams.credentials.password === "__PWRD__") {
// The password isn't changed or (the server node was already present, it's only updated)
_nodeServer = RED.nodes.getNode(req.query.nodeID);// Retrieve node.id of the config node.
if (jParams.authentication === "digest") clientInfo = new DigestFetch(jParams.credentials.user, _nodeServer.credentials.password); // Instantiate the fetch client.
if (jParams.authentication === "basic") clientInfo = new DigestFetch(jParams.credentials.user, _nodeServer.credentials.password, { basic: true }); // Instantiate the fetch client.
} else {
// The node is NEW
if (jParams.authentication === "digest") clientInfo = new DigestFetch(jParams.credentials.user, jParams.credentials.password); // Instantiate the fetch client.
if (jParams.authentication === "basic") clientInfo = new DigestFetch(jParams.credentials.user, jParams.credentials.password, { basic: true }); // Instantiate the fetch client.
}
var opt = {
// These properties are part of the Fetch Standard
method: "PUT",
headers: {}, // request headers. format is the identical to that accepted by the Headers constructor (see below)
body: null, // request body. can be null, a string, a Buffer, a Blob, or a Node.js Readable stream
redirect: 'follow', // set to `manual` to extract redirect headers, `error` to reject redirect
signal: null, // pass an instance of AbortSignal to optionally abort requests
// The following properties are node-fetch extensions
follow: 20, // maximum redirect count. 0 to not follow redirect
timeout: 5000, // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies). Signal is recommended instead.
compress: false, // support gzip/deflate content encoding. false to disable
size: 0, // maximum response body size in bytes. 0 to disable
agent: jParams.protocol === "https" ? customHttpsAgent : null // http(s).Agent instance or function that returns an instance (see below)
};
try {
(async () => {
try {
// const resInfo = await clientInfo.fetch(jParams.protocol + "://" + jParams.host + ":" + jParams.port + "/ISAPI/AccessControl/EventCardLinkageCfg/CustomAudio?format=json", opt);
const resInfo = await clientInfo.fetch(jParams.protocol + "://" + jParams.host + "/ISAPI/Event/triggers/notifications/AudioAlarm/AudioOut/1/PlayCustomAudioFile?format=json&customAudioID=" + customAudioID + "&audioVolume=2&loopPlaybackTimes=1", opt);
const body = await resInfo.json();
res.json({});
return;
} catch (error) {
RED.log.error("Errore hikvisionUltimateGetInfoSpeaker " + error.message);
res.json(error);
}
})();

@@ -148,3 +199,83 @@

// PLAY THE FILE ALOUD VIA THE SPEAKER
node.playAloud = async function (_customAudioID, _volume) {
var jParams = node;
var clientInfo;
// Set Auth
if (jParams.authentication === "digest") clientInfo = new DigestFetch(jParams.credentials.user, jParams.credentials.password); // Instantiate the fetch client.
if (jParams.authentication === "basic") clientInfo = new DigestFetch(jParams.credentials.user, jParams.credentials.password, { basic: true }); // Instantiate the fetch client.
var opt = {
// These properties are part of the Fetch Standard
method: "PUT",
headers: {}, // request headers. format is the identical to that accepted by the Headers constructor (see below)
body: JSON.stringify({ "audioOutID": [1] }), // request body.
redirect: 'follow', // set to `manual` to extract redirect headers, `error` to reject redirect
signal: null, // pass an instance of AbortSignal to optionally abort requests
// The following properties are node-fetch extensions
follow: 20, // maximum redirect count. 0 to not follow redirect
timeout: 5000, // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies). Signal is recommended instead.
compress: false, // support gzip/deflate content encoding. false to disable
size: 0, // maximum response body size in bytes. 0 to disable
agent: jParams.protocol === "https" ? customHttpsAgent : null // http(s).Agent instance or function that returns an instance (see below)
};
try {
// STOP PLAYING PREVIOUS FILE, IF ANY
const resInfoStop = await clientInfo.fetch(jParams.protocol + "://" + jParams.host + "/ISAPI/AccessControl/EventCardLinkageCfg/CustomAudio/" + _customAudioID + "/stop?format=json", opt);
// PLAY THE FILE
const resInfo = await clientInfo.fetch(jParams.protocol + "://" + jParams.host + "/ISAPI/Event/triggers/notifications/AudioAlarm/AudioOut/1/PlayCustomAudioFile?format=json&customAudioID=" + _customAudioID + "&audioVolume=" + _volume + "&loopPlaybackTimes=1", opt);
const body = await resInfo.json();
if (body.statusCode === 1) {
return true;
} else {
return false;
}
} catch (error) {
RED.log.error("Errore playAloud Stop " + error.message);
return false;
}
};
node.stopFile = async function (_customAudioID) {
var jParams = node;
var clientInfo;
// Set Auth
if (jParams.authentication === "digest") clientInfo = new DigestFetch(jParams.credentials.user, jParams.credentials.password); // Instantiate the fetch client.
if (jParams.authentication === "basic") clientInfo = new DigestFetch(jParams.credentials.user, jParams.credentials.password, { basic: true }); // Instantiate the fetch client.
var opt = {
// These properties are part of the Fetch Standard
method: "PUT",
headers: {}, // request headers. format is the identical to that accepted by the Headers constructor (see below)
body: JSON.stringify({ "audioOutID": [1] }), // request body.
redirect: 'follow', // set to `manual` to extract redirect headers, `error` to reject redirect
signal: null, // pass an instance of AbortSignal to optionally abort requests
// The following properties are node-fetch extensions
follow: 20, // maximum redirect count. 0 to not follow redirect
timeout: 5000, // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies). Signal is recommended instead.
compress: false, // support gzip/deflate content encoding. false to disable
size: 0, // maximum response body size in bytes. 0 to disable
agent: jParams.protocol === "https" ? customHttpsAgent : null // http(s).Agent instance or function that returns an instance (see below)
};
// STOP PLAYING PREVIOUS FILE
try {
// const resInfo = await clientInfo.fetch(jParams.protocol + "://" + jParams.host + ":" + jParams.port + "/ISAPI/AccessControl/EventCardLinkageCfg/CustomAudio?format=json", opt);
const resInfo = await clientInfo.fetch(jParams.protocol + "://" + jParams.host + "/ISAPI/AccessControl/EventCardLinkageCfg/CustomAudio/" + _customAudioID + "/stop?format=json", opt);
const body = await resInfo.json();
if (body.statusCode === 1) {
return true;
} else {
return false;
}
} catch (error) {
RED.log.error("Errore stopFile Stop " + error.message);
return false;
}
}
//#region "HANDLE STREAM MESSAGE"

@@ -297,53 +428,5 @@ // Handle the complete stream message, enclosed into the --boundary stream string

//#region GENERIC GET OT PUT CALL
// Function to get or post generic data on device
node.request = async function (_callerNode, _method, _URL, _body) {
var clientGenericRequest;
if (node.authentication === "digest") clientGenericRequest = new DigestFetch(node.credentials.user, node.credentials.password); // Instantiate the fetch client.
if (node.authentication === "basic") clientGenericRequest = new DigestFetch(node.credentials.user, node.credentials.password, { basic: true }); // Instantiate the fetch client.
var reqController = new AbortController(); // For aborting the stream request
var options = {
// These properties are part of the Fetch Standard
method: _method.toString().toUpperCase(),
headers: {}, // request headers. format is the identical to that accepted by the Headers constructor (see below)
body: _body, // request body. can be null, a string, a Buffer, a Blob, or a Node.js Readable stream
redirect: 'follow', // set to `manual` to extract redirect headers, `error` to reject redirect
signal: reqController.signal, // pass an instance of AbortSignal to optionally abort requests
// The following properties are node-fetch extensions
follow: 20, // maximum redirect count. 0 to not follow redirect
timeout: 8000, // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies). Signal is recommended instead.
compress: false, // support gzip/deflate content encoding. false to disable
size: 0, // maximum response body size in bytes. 0 to disable
agent: node.protocol === "https" ? customHttpsAgent : null // http(s).Agent instance or function that returns an instance (see below)
};
try {
if (!_URL.startsWith("/")) _URL = "/" + _URL;
const response = await clientGenericRequest.fetch(node.protocol + "://" + node.host + _URL, options);
if (response.ok) {
try {
const oReadable = readableStr.from(response.body, { encoding: 'utf8' });
oReadable.on('data', (chunk) => {
if (node.debug) RED.log.error(chunk);
});
} catch (error) {
throw new Error("Error readableStream: " + error.message || "");
}
} else {
throw new Error("Error response: " + response.statusText || " unknown response code");
}
} catch (error) {
// Main Error
if (node.debug) RED.log.error("Speaker-config: clientGenericRequest.fetch error " + error.message);
throw (new Error("clientGenericRequest.fetch error:" + error.message));
}
};
//#endregion
//#region "FUNCTIONS"
//#region "Base FUNCTIONS"
node.on('close', function (removed, done) {

@@ -350,0 +433,0 @@ if (controller !== null) {

{
"name": "node-red-contrib-hikvision-ultimate",
"version": "1.1.18",
"version": "1.1.19",
"description": "A native set of nodes for Hikvision (and compatible) Cameras, Alarms, Radars, NVR, Doorbells, etc.",

@@ -37,6 +37,2 @@ "author": "Supergiovane (https://github.com/Supergiovane)",

"nodes": {
"Hikvision-config": "nodes/Hikvision-config.js",
"AXPro-config": "nodes/AXPro-config.js",
"Doorbell-config": "nodes/Doorbell-config.js",
"ANPR-config": "nodes/ANPR-config.js",
"AccessControl-config": "nodes/AccessControl-config.js",

@@ -52,5 +48,11 @@ "hikvisionUltimateText": "nodes/hikvisionUltimateText.js",

"hikvisionUltimateAxPro": "nodes/hikvisionUltimateAxPro.js",
"hikvisionUltimateAccessControlTerminal": "nodes/hikvisionUltimateAccessControlTerminal.js"
"hikvisionUltimateAccessControlTerminal": "nodes/hikvisionUltimateAccessControlTerminal.js",
"hikvisionUltimateSpeaker": "/nodes/hikvisionUltimateSpeaker.js",
"Hikvision-config": "nodes/Hikvision-config.js",
"AXPro-config": "nodes/AXPro-config.js",
"Doorbell-config": "nodes/Doorbell-config.js",
"ANPR-config": "nodes/ANPR-config.js",
"Speaker-config": "/nodes/Speaker-config.js"
}
}
}
<p align="center"><img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/logo.png' width="60%"></p>
<p align="center"><img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/logo.png'></p>

@@ -27,3 +27,3 @@ A native set of nodes for Hikvision (and compatible) Cameras, Alarms, Radars, NVR, Doorbells etc.

For NVR/DVR, pleas remember to select "Notify Alarm Center" in the event window, otherwise the NVR won't emit any alarm event.<br/>
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/NotifyCenter.png' width="30%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/NotifyCenter.png'>

@@ -45,3 +45,3 @@ ## COLLABORATORS NEEDED

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/hikcamera.jpg' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/hikcamera.jpg' >

@@ -55,3 +55,3 @@ The Camera Event node connects to ***NVR, Camera, Radars, etc..*** and outputs true/false in case of an alarm. <br/>

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/GenericAlarm.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/GenericAlarm.png' >

@@ -143,3 +143,3 @@ You can choose from many different alarms, including: <br/>

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/hikanprcamera.jpg' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/hikanprcamera.jpg' >

@@ -149,3 +149,3 @@

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/ANPR.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/ANPR.png' >

@@ -189,3 +189,3 @@ **Flow Messages**

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/hikptzcamera.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/hikptzcamera.png' >

@@ -196,3 +196,3 @@ Recalls a PTZ pre-recorded preset.<br/>

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/PTZ.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/PTZ.png' >

@@ -244,3 +244,3 @@ **Flow Messages**

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/hikcamerasettings.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/hikcamerasettings.png' >

@@ -254,3 +254,3 @@ This node gets a picture from the camera/NVR, ready to be shown in the dashboard UI.<br/>

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/picture.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/picture.png' >

@@ -285,3 +285,3 @@ <br/>

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/pictureproperties.png' width="30%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/pictureproperties.png'>

@@ -344,3 +344,3 @@ **Flow Messages**

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/Text.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/Text.png' >

@@ -414,3 +414,3 @@ **Copy this code and paste it into your flow**

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/XML.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/XML.png' >

@@ -533,3 +533,3 @@

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/RawAlarm.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/RawAlarm.png' >

@@ -598,3 +598,3 @@ **Flow Messages**

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/Doorbell.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/Doorbell.png' >

@@ -684,3 +684,3 @@ **Copy this code and paste it into your flow**

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/axproPicture.jpg' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/axproPicture.jpg' >

@@ -692,3 +692,3 @@

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/axpro.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/axpro.png' >

@@ -805,7 +805,7 @@ **Copy this code and paste it into your flow**

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/CIDEvents/1.png' width="100%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/CIDEvents/2.png' width="100%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/CIDEvents/3.png' width="100%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/CIDEvents/4.png' width="100%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/CIDEvents/5.png' width="100%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/CIDEvents/1.png' >>
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/CIDEvents/2.png' >>
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/CIDEvents/3.png' >>
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/CIDEvents/4.png' >>
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/CIDEvents/5.png' >>

@@ -819,3 +819,3 @@ <br/>

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/accesscontrolterminal.jpg' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/accesscontrolterminal.jpg'>

@@ -827,3 +827,3 @@

<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/accesscontrol.png' width="80%">
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/accesscontrol.png' >

@@ -860,7 +860,17 @@ <br/>

<br/>
<br/>
## Speaker node
<img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/speaker.jpg' >
This node connects to your Hikvision Speaker and broadcast a selected audio file, that must be already been uploaded to the speaker.<br/>
Please see the help into the Node-Red help tab for further infos.
![Logo](https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/madeinitaly.png)

@@ -867,0 +877,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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