Hi All
I am new to node-red and have been trying to use it to connect to a BLE battery monitor. After a little scratching of my head and a lot of googling, I have managed to get the nodes to connect (using node-red-contrib-noble-bluetooth) nodes.
After leaving the flow running for a while I get the following error message:
(node:3459) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 stateChange listeners added. Use emitter.setMaxListeners() to increase limit.
I have also had:
(node:26198) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 disconnect listeners added. Use emitter.setMaxListeners() to increase limit.
I have tracked the issue to the BLE device node, but am unsure what is happening internally.
It looks like each time I deploy a change to the flow, the node disconnects from the device. I then run a scan and it reconnects. After a number of repeats I get the error messages, usually the second one. I am assuming that the code in the node is not clearing all the listeners at each disconnect/reconnect.
I am new to node.js so am not sure if its node-red or the code underneath that's causing the issue.
"
function BLEDeviceNode(config) {
RED.nodes.createNode(this,config);
var node = this;
// disconnect function
function deviceDisconnected() {
node.status({});
var msg = {}
msg.connected = false;
msg.connectable = node._peripheral.connectable;
msg.peripheral = node._peripheral.id;
msg.address = node._peripheral.address;
msg.topic = "disconnected";
node.send(msg);
}
node.on('input', function(msg) {
// check to see if we have a valid peripheral
//if not then red dot
if (!msg.peripheral) {
node.status({ fill: "red", shape: "dot", text: "invalid peripheral id" });
return;
}
// not sure what this is doing, but looks like its checking for a valid object
if(node._peripheral) {
node._peripheral.removeListener('disconnect', deviceDisconnected);
}
node._peripheral = noble._peripherals[msg.peripheral];
//node._services = null;
//node._characteristics = null;
var peripheral = node._peripheral;
peripheral.connect(function(error) {
if (error) {
node.error("Error connecting: " + error);
node.status({ fill: "red", shape: "dot", text: "error connecting" });
return;
}
msg.connected = true;
msg.connectable = peripheral.connectable;
msg.rssi = peripheral.rssi;
node.on('close', function(done) {
peripheral.disconnect();
done();
});
// think this is in the wrong place
peripheral.once('disconnect', deviceDisconnected);
node.status({ fill: "green", shape: "dot", text: "connecting" });
peripheral.discoverAllServicesAndCharacteristics(function(error, services, characteristics) {
if (error) {
node.error("Error discovering services: " + error);
node.status({ fill: "red", shape: "dot", text: "error finding services" });
return;
}
var services_ = [];
//node._services = services;
services.forEach(function(value, index, array) {
var service_ = {};
service_.uuid = value.uuid;
service_.name = value.name;
service_.type = value.type;
var serviceChars_ = [];
value.characteristics.forEach(function(value_, index_, array_) {
var serviceChar_ = {};
serviceChar_.uuid = value_.uuid;
serviceChar_.serviceUuid = service_.uuid;
serviceChar_.name = value_.name;
serviceChar_.type = value_.type;
serviceChar_.properties = value_.properties;
serviceChars_.push(serviceChar_);
});
service_.characteristics = serviceChars_;
services_.push(service_);
});
msg.services = services_;
var characteristics_ = [];
//node._characteristics = characteristics;
characteristics.forEach(function(value, index, array) {
var characteristic_ = {};
characteristic_.uuid = value.uuid;
characteristic_.serviceUuid = value._serviceUuid;
characteristic_.name = value.name;
characteristic_.type = value.type;
characteristic_.properties = value.properties;
characteristics_.push(characteristic_);
});
msg.characteristics = characteristics_;
msg.topic = "connected";
msg._peripheral = peripheral;
node.status({ fill: "green", shape: "dot", text: "connected" });
node.send(msg);
});
});
});
node.on('close', function(done) {
done();
});
}
RED.nodes.registerType("BLE device",BLEDeviceNode);
this is the node code, I have marked a couple of areas I am not sure about, but can't see where the disconnect Listner is added or removed.
Any help would be appreciated.
Thanks