Events from the first camera are duplicated to all others, events from other cameras do not come
reason here:
Cam.prototype.on('newListener', function(name) {
// if there is the first listener, start pulling
console.info(this.hostname, 'newListener', this.listeners(name), this.listenerCount(name));
if (name === 'event' && this.listeners(name).length === 0) {
this._eventRequest();
}
});
for some reason this.listeners(name) is global here
for test this issue:
let Cam = require('./lib/onvif').Cam;
let flow = require('nimble');
const callback = function CamFunc(err) {
if (err) {
console.log(err);
return;
}
console.log('Connected to ONVIF Device');
let cam_obj = this;
let hasEvents = false;
let hasTopics = false;
let name = "";
// Use Nimble's flow to execute ONVIF commands in sequence
flow.series([
function(callback) {
cam_obj.getDeviceInformation(function(err, info, xml) {
if (!err) console.log('Manufacturer ' + info.manufacturer);
if (!err) console.log('Model ' + info.model);
if (!err) console.log('Firmware ' + info.firmwareVersion);
if (!err) console.log('Serial Number ' + info.serialNumber);
name = info.serialNumber;
callback();
});
},
function(callback) {
cam_obj.getCapabilities(function(err, data, xml) {
if (err) {
console.log(err);
}
if (!err && data.events && data.events.WSPullPointSupport && data.events.WSPullPointSupport == true) {
console.log('Camera supports WSPullPoint');
hasEvents = true;
} else {
console.log('Camera does not show WSPullPoint support, but trying anyway');
// Have an Axis cameras that says False to WSPullPointSuppor but supports it anyway
hasEvents = true; // Hack for Axis cameras
}
if (hasEvents == false) {
console.log('This camera/NVT does not support PullPoint Events')
}
callback();
});
},
function(callback) {
if (hasEvents) {
cam_obj.getEventProperties(function(err, data, xml) {
if (err) {
console.log(err);
}
else {
// Display the available Topics
let parseNode = function(node, topicPath) {
// loop over all the child nodes in this node
for (const child in node) {
if (child == "$") continue;
else if (child == "messageDescription") {
// we have found the details that go with an event
// examine the messageDescription
let IsProperty = false;
let source = '';
let data = '';
if (node[child].$ && node[child].$.IsProperty) IsProperty = node[child].$.IsProperty;
if (node[child].source) source = JSON.stringify(node[child].source)
if (node[child].data) data = JSON.stringify(node[child].data)
console.log('Found Event - ' + topicPath.toUpperCase())
//console.log(' IsProperty=' + IsProperty);
//if (source.length > 0) console.log(' Source=' + source);
//if (data.length > 0) console.log(' Data=' + data);
hasTopics = true;
return;
}
else {
// decend into the child node, looking for the messageDescription
parseNode(node[child], topicPath + '/' + child)
}
}
}
parseNode(data.topicSet, '');
}
callback();
});
} else {
callback();
}
},
function(callback) {
if (hasEvents && hasTopics) {
cam_obj.on('event', camMessage => {
// Extract Event Details
let eventTime = camMessage.message.message.$.UtcTime
let eventTopic = camMessage.topic._;
let eventProperty = camMessage.message.message.$.PropertyOperation
// there can be more than one SimpleItem in the 'data' part of the XML
let eventType;
let eventValue;
if (Array.isArray(camMessage.message.message.data)) {
eventType = camMessage.message.message.data.simpleItem.$.Name
eventValue = camMessage.message.message.data.simpleItem.$.Value
} else {
eventType = camMessage.message.message.data.simpleItem.$.Name
eventValue = camMessage.message.message.data.simpleItem.$.Value
}
console.log(`${name} EVENT TRIGGERED: ${eventTime.toJSON()} ${eventTopic} ${eventProperty} ${eventType} ${eventValue}`);
})
}
callback();
}
]);
// Code completes here but the applictions remains running as there is a OnEvent listener that is active
// To stop we must remove the event listener
//setTimeout(()=>{cam_obj.removeAllListeners('event');},5000);
}
new Cam({
hostname : "cam1",
username : "admin",
password : "admin",
port : 80,
timeout : 10000,
preserveAddress : true // Enables NAT support and re-writes for PullPointSubscription URL
}, callback);
new Cam({
hostname : "cam2",
username : "admin",
password : "admin",
port : 80,
timeout : 10000,
preserveAddress : true // Enables NAT support and re-writes for PullPointSubscription URL
}, callback);
Events from the first camera are duplicated to all others, events from other cameras do not come
reason here:
in log:
for some reason this.listeners(name) is global here
for test this issue: