UNPKG

node-red-contrib-hikvision-ultimate

Version:

A native set of nodes for Hikvision (and compatible) Cameras, Alarms, Radars, NVR, Doorbells, etc.

98 lines (84 loc) 3.85 kB
module.exports = function (RED) { function hikvisionUltimatePTZ(config) { RED.nodes.createNode(this, config); var node = this; node.topic = config.topic || node.name; node.server = RED.nodes.getNode(config.server) const isDebug = node.server && node.server.debug; const logDebug = (text) => { if (isDebug) RED.log.info(`hikvisionUltimatePTZ: ${text}`); }; node.PTZPreset = (config.PTZPreset === null || config.PTZPreset === undefined) ? "1" : config.PTZPreset; node.channelID = (config.channelID === null || config.channelID === undefined) ? "1" : config.channelID; node.setNodeStatus = ({ fill, shape, text }) => { var dDate = new Date(); node.status({ fill: fill, shape: shape, text: text + " (" + dDate.getDate() + ", " + dDate.toLocaleTimeString() + ")" }) } // Called from config node, to send output to the flow node.sendPayload = (_msg) => { if (_msg === null || _msg === undefined) return; if (_msg.type !== undefined && _msg.type === 'img') { // The payload is an image, exit. return; } _msg.topic = node.topic; if (_msg.hasOwnProperty("errorDescription")) { node.send([null, _msg]); return; }; // It's a connection error/restore comunication. if (!_msg.hasOwnProperty("payload") || (_msg.hasOwnProperty("payload") && _msg.payload === undefined)) return; if (_msg.hasOwnProperty("payload")) { if (_msg.payload.hasOwnProperty("eventType")) { // Chech if it's only a hearbeat alarm try { var sAlarmType = _msg.payload.eventType.toString().toLowerCase(); if (sAlarmType === "videoloss" && _msg.payload.hasOwnProperty("activePostCount") && _msg.payload.activePostCount == "0") { node.setNodeStatus({ fill: "green", shape: "ring", text: "Received HeartBeat (the device is online)" }); logDebug("Heartbeat received from device, skipping PTZ recall"); return; // It's a Heartbeat } } catch (error) { } } } node.send([_msg, null]); node.setNodeStatus({ fill: "green", shape: "dot", text: "PTZ Pteset recalled." }); logDebug(`Forwarded PTZ event for channel ${node.channelID} preset ${node.PTZPreset}`); } // On each deploy, unsubscribe+resubscribe if (node.server) { node.server.removeClient(node); node.server.addClient(node); } this.on('input', function (msg) { if (msg === null || msg === undefined) return; if (msg.hasOwnProperty("payload") && msg.hasOwnProperty("payload") !== null && msg.hasOwnProperty("payload") !== undefined) { if (typeof msg.payload === "boolean" && msg.payload === true) { logDebug(`Recall PTZ preset ${node.PTZPreset} on channel ${node.channelID} (boolean trigger)`); recallPTZ(); } else if (typeof msg.payload === "object") { // Set the preset via input msg if (msg.payload.hasOwnProperty("channelID")) node.channelID = msg.payload.channelID; if (msg.payload.hasOwnProperty("PTZPreset")) node.PTZPreset = msg.payload.PTZPreset; node.setNodeStatus({ fill: "green", shape: "dot", text: "Preset passed by msg input." }); logDebug(`Recall PTZ with payload overrides: channel ${node.channelID} preset ${node.PTZPreset}`); recallPTZ(); } } }); // Recalls the PTZ function recallPTZ() { // Recall PTZ Preset // Params: _callerNode, _method, _URL, _body try { logDebug(`Sending PTZ goto preset request channel ${node.channelID}, preset ${node.PTZPreset}`); node.server.request(node, "PUT", "/ISAPI/PTZCtrl/channels/" + node.channelID + "/presets/" + node.PTZPreset + "/goto", ""); } catch (error) { logDebug(`Error sending PTZ command: ${error.message || error}`); } } node.on("close", function (done) { if (node.server) { node.server.removeClient(node); } done(); }); } RED.nodes.registerType("hikvisionUltimatePTZ", hikvisionUltimatePTZ); }