UNPKG

node-red-contrib-hikvision-ultimate

Version:

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

134 lines (120 loc) 4.99 kB
const _ = require('lodash') module.exports = function (RED) { function hikvisionUltimateAxPro(config) { RED.nodes.createNode(this, config); var node = this; node.topic = config.topic || config.name; node.server = RED.nodes.getNode(config.server) const isDebug = node.server && node.server.debug; const logDebug = (text) => { if (isDebug) RED.log.info(`hikvisionUltimateAxPro: ${text}`); }; node.zonesStatus = [] // Contains the status of all zones node.outputtype = Number(config.outputtype || 0) 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; _msg.topic = node.topic; if (_msg.hasOwnProperty("errorDescription")) { logDebug(`Connection status message: ${_msg.errorDescription || ""}`); node.send([null, _msg]); return; }; // It's a connection error/restore comunication. // If heartbeat, return if (_msg.payload.hasOwnProperty("eventType") && _msg.payload.hasOwnProperty("eventState") && _msg.payload.eventType === "cidEvent" && _msg.payload.eventState === "inactive") { logDebug("Heartbeat received from AX Pro, ignored"); return } if ((node.outputtype === 0 || node.outputtype === 1) && _msg.payload.hasOwnProperty('CIDEvent')) { // ALARM EVENT logDebug(`Forwarding CIDEvent code ${_msg.payload.CIDEvent.code || "n/a"} zone ${_msg.payload.CIDEvent.zone !== undefined ? _msg.payload.CIDEvent.zone + 1 : "n/a"}`); node.send([{ payload: { CIDEvent: RED.util.cloneMessage(_msg.payload.CIDEvent) } }, null]); // Clone message to avoid adding _msgid } if ((node.outputtype === 0 || node.outputtype === 2) && _msg.payload.hasOwnProperty('ZoneList')) { // CHECK ONLY THE CHANGED ZONE STATUS for (let index = 0; index < _msg.payload.ZoneList.length; index++) { try { const receivedZone = _msg.payload.ZoneList[index].Zone; let foundInZoneStatus = node.zonesStatus.find((element) => element.id === receivedZone.id) if (!_.isEqual(foundInZoneStatus, receivedZone)) { if (foundInZoneStatus === undefined) { node.zonesStatus.push(receivedZone) // Add updated } else { node.zonesStatus[node.zonesStatus.findIndex((element) => element.id === receivedZone.id)] = receivedZone //node.zonesStatus.splice(foundInZoneStatus) //node.zonesStatus.push(receivedZone) // Add updated } node.setNodeStatus({ fill: "green", shape: "dot", text: "Zone changed " + receivedZone.name }); logDebug(`Zone ${receivedZone.id} (${receivedZone.name}) changed state to ${receivedZone.status || "unknown"}`); node.send([{ payload: { zoneUpdate: RED.util.cloneMessage(receivedZone) } }, null]); // Clone message to avoid adding _msgid } } catch (error) { } } } else { //node.send([_msg, null]) node.setNodeStatus({ fill: "green", shape: "ring", text: "Waiting for zone change" }); logDebug("Zone update received without changes after filters"); } } // On each deploy, unsubscribe+resubscribe if (node.server) { node.server.removeClient(node); node.server.addClient(node); } this.on('input', function (msg) { try { // Disarm Area if (msg.hasOwnProperty("disarmArea")) { logDebug(`Disarm area ${msg.disarmArea}`); node.server.disarmArea(msg.disarmArea) } // Arm Away Area if (msg.hasOwnProperty("armAwayArea")) { logDebug(`Arm away area ${msg.armAwayArea}`); node.server.armAwayArea(msg.armAwayArea) } // Arm Stay Area if (msg.hasOwnProperty("armStayArea")) { logDebug(`Arm stay area ${msg.armStayArea}`); node.server.armStayArea(msg.armStayArea) } // Arm Away All Areas in a batch if (msg.hasOwnProperty("armAwayAllAreas")) { logDebug("Arm away all areas"); node.server.armAwayAllAreas() } // Arm Stay All Areas in a batch if (msg.hasOwnProperty("armStayAllAreas")) { logDebug("Arm stay all areas"); node.server.armStayAllAreas() } // Clear Alarm Area if (msg.hasOwnProperty("clearAlarmArea")) { logDebug(`Clear alarm area ${msg.clearAlarmArea}`); node.server.clearAlarmArea(msg.clearAlarmArea) } // Disarm All Area in a batch if (msg.hasOwnProperty("disarmAllAreas")) { logDebug("Disarm all areas"); node.server.disarmAllAreas() } // Clear All Alarm Areas if (msg.hasOwnProperty("clearAllAlarmAreas")) { logDebug("Clear all alarm areas"); node.server.clearAllAlarmAreas() } } catch (error) { } }); node.on("close", function (done) { if (node.server) { node.server.removeClient(node); } done(); }); } RED.nodes.registerType("hikvisionUltimateAxPro", hikvisionUltimateAxPro); }