I am connecting some digital inputs on my Siemens Simatic IoT2000 products, unfortunately none of the existing nodes are working well, so I have started to create my own. Now the behaviour is fine since I have added a callback function. But I still have an annoying bug. If I redeploy my flow then I have 2 readings of the pin, if I deploy a third time then I have 3 readings ... so to avoid that each time I deploy a modified flow with those nodes I have to restart my Node-RED.
I am pretty sure it has to do with a poor clearance of the TimeOut, but I have not been able to figure it out so far .
I have modified the function as per below, but the behaviour is still the same after a reboot.
function newSetInterval(callback, duration, callbackArguments)
{
callback.apply(this, callbackArguments);
var args = arguments,
scope=this;
return setTimeout(function() {newSetInterval.apply(scope, args);}, duration);
}
If I deploy without rebooting I get multiple reads. The missing return was a clear reason not to work I got that now, so maybe it seems clearTimeout is not implemented correctly.
The initial node were using setInterval/clearInterval, but they bug, and crash Node-RED within minutes of use. I saw that a generic issue with setInterval was due to the function running longer than the interval time, hence I try to add a callback, and since I added it I have no more problem like that, it works perfectly but needs a restart.
var sys = require('util')
var exec = require('child_process').exec;
module.exports = function(RED) {
var mraa = require('mraa');
exec("echo 63 > /sys/class/gpio/export");
function gpioDin(n) {
RED.nodes.createNode(this,n);
var node = this;
node.pin = n.pin;
node.updateInterval = n.updateInterval;
node.mGpio = new mraa.Gpio(parseInt(node.pin));
node.mGpio.mode(mraa.PIN_GPIO);
node.mGpio.dir(mraa.DIR_IN);
var lastPinState = node.mGpio.read();
var currentPinState = 0;
var timerId = setInterval(function()
{
if(node.pin != "ub")
{
currentPinState = node.mGpio.read();
}
else
{
exec("cat /sys/class/gpio/gpio63/value", function(error, stdout, stderr) {
currentPinState = parseInt(stdout);
});
}
if(currentPinState == 0 || currentPinState == 1)
{
if (currentPinState != lastPinState)
{
var msg = { payload:currentPinState, topic:"D"+node.pin };
node.send(msg);
}
lastPinState = currentPinState;
}
},parseInt(node.updateInterval));
this.on('close', function() {
clearInterval(timerId);
});
}
RED.nodes.registerType("IoT2000-gpio-din", gpioDin);
So I am not sure which direction to go to solve this issue.