Weird things happening. CPU load spikes

Is this any better/closer to working?

//  node.send()

var sunset;
var z = 0;
var msg1;
var msg2;
var delay_time;
if (msg.delay_time == undefined)
    msg.delay_time = 4000;
delay_time = msg.delay_time;
if (msg.sunset == undefined)
    msg.sunset = "196,10,0";
sunset = msg.sunset;

msg1 = "rgb,0,"+sunset;
msg2 = "X";

//node.warn("Msg1 " + msg1);
//node.warn("Msg2 " + msg2);

//  Delay
f(delay_time,z,msg1,msg2);

//------------------

msg1 = "rgb,1,"+sunset;
msg2 = "X";

//  Delay
f(delay_time,z,msg1,msg2);

//------------------

if (msg.existing[0] == undefined)
{
    msg.existing[0] = "0,0,0";
}
msg1 = "rgb,2,"+sunset;
msg2 = msg.existing;

//  Delay
f(delay_time,z,msg1,msg2);

//------------------

if (msg.existing[1] == undefined)
{
    msg.existing[1] = "0,0,0";
}
msg1 = "rgb,3,"+sunset;
msg2 = msg.existing;

//  Delay
f(delay_time,z,msg1,msg2);

//------------------

if (msg.existing[2] == undefined)
{
    msg.existing[2] = "0,0,0";
}
msg1 = "rgb,4,"+sunset;
msg2 = msg.existing;

//  Delay
f(delay_time,z,msg1,msg2);

//------------------

if (msg.existing[3] == undefined)
{
    msg.existing[3] = "0,0,0";
}
msg1 = "rgb,5,"+sunset;
msg2 = msg.existing;

//  Delay
f(delay_time,z,msg1,msg2);

//------------------

if (msg.existing[4] == undefined)
{
    msg.existing[4] = "0,0,0";
}
msg1 = "rgb,6,"+sunset;
msg2 = msg.existing;

//  Delay
f(delay_time,z,msg1,msg2);

//------------------

if (msg.existing[5] == undefined)
{
    msg.existing[5] = "0,0,0";
}
msg1 = "rgb,7,"+sunset;
msg2 = msg.existing;

//  Delay
f(delay_time,z,msg1,msg2);

//------------------

if (msg.existing[6] == undefined)
{
    msg.existing[6] = "0,0,0";
}
msg1 = "X";
msg2 = msg.existing;

//msg.payload = "rgb,6,"+msg.existing[6];
//  Delay
f(delay_time,z,msg1,msg2);

//------------------

if (msg.existing[7] == undefined)
{
    msg.existing[7] = "0,0,0";
}
msg1 = "X";
msg2 = msg.existing;

//msg.payload = "rgb,7,"+msg.existing[7];
node.send(msg2);

return;

function f(delay_time,z,msg1,msg2)
{
    //
    node.warn("Messages received " + delay_time + " - " + z + " - " + msg1 + " - " + msg2);
    if (msg1 != "X")
    {
        msg.payload = msg1;
        node.send(msg);
    }
    if (msg2 != "X")
    {
        msg.payload = msg2;
        node.send(msg);
    }
    z += 1;
    if (z < delay_time){
        setTimeout(f, delay_time,z);
    }
}

f(delay_time,z,msg1,msg2);

Andrew, I beleive you are attempting to send messages evenly spaced out by the ms set in delay_time using a function node and settimeout

Here is your function re-worked.

if (msg.delay_time == undefined)
    msg.delay_time = 4000;
var delay_time = msg.delay_time;
if (msg.sunset == undefined)
    msg.sunset = "196,10,0";
var sunset = msg.sunset;

sendLater(0, msg, "rgb,0," + sunset);
sendLater(delay_time * 1, msg, "rgb,1," + sunset);
sendLater(delay_time * 2, msg, "rgb,1," + sunset);
sendLater(delay_time * 3, msg, "rgb,2," + sunset);
if (msg.existing[0] == undefined) {
    msg.existing[0] = "0,0,0";
}
sendLater(delay_time * 4, msg, "rgb,0," + msg.existing[0]);
sendLater(delay_time * 5, msg, "rgb,3," + sunset);
if (msg.existing[1] == undefined) {
    msg.existing[1] = "0,0,0";
}
sendLater(delay_time * 6, msg, "rgb,1," + msg.existing[1]);
sendLater(delay_time * 7, msg, "rgb,4," + sunset);
if (msg.existing[2] == undefined) {
    msg.existing[2] = "0,0,0";
}
sendLater(delay_time * 8, msg, "rgb,2," + msg.existing[2]);
sendLater(delay_time * 9, msg, "rgb,5," + sunset);
if (msg.existing[3] == undefined) {
    msg.existing[3] = "0,0,0";
}
sendLater(delay_time * 10, msg, "rgb,3," + msg.existing[3]);
sendLater(delay_time * 11, msg, "rgb,6," + sunset);
if (msg.existing[4] == undefined) {
    msg.existing[4] = "0,0,0";
}
sendLater(delay_time * 12, msg, "rgb,4," + msg.existing[4]);
sendLater(delay_time * 13, msg, "rgb,7," + sunset);

if (msg.existing[5] == undefined) {
    msg.existing[5] = "0,0,0";
}
sendLater(delay_time * 14, msg, "rgb,5," + msg.existing[5]);
if (msg.existing[6] == undefined) {
    msg.existing[6] = "0,0,0";
}
sendLater(delay_time * 15, msg, "rgb,6," + msg.existing[6]);

if (msg.existing[7] == undefined) {
    msg.existing[7] = "0,0,0";
}
sendLater(delay_time * 16, msg, "rgb,7," + msg.existing[7]);

/**
* @param {number} delayMS
* @param {NodeMessage} msg
* @param {string} payload
*/
function sendLater(delayMS, msg, payload) {
    node.warn(`In sendLater(${delayMS},${msg},${payload}) - setting up a timer to send payload '${payload}' in ${(delayMS/1000).toFixed(2)} seconds time`)
    const callback = function (msg, payload) {
        node.warn("Sending delayed payload " + payload);
        msg.payload = payload;
        node.send(msg);
    }
    setTimeout(callback, delayMS, RED.util.cloneMessage(msg), payload)
}

Here is a test flow so you can check it does what you expect (put it on a node-red that is not doing a million other things so you can see its output is as you expect...

[{"id":"47ba4118261ff5d7","type":"inject","z":"b872cb4b.5a6448","name":"500ms","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"existing","v":"[]","vt":"json"},{"p":"delay_time","v":"500","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":1530,"y":340,"wires":[["03a5f0701303bafd"]]},{"id":"56e2873e77a8f625","type":"debug","z":"b872cb4b.5a6448","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1950,"y":340,"wires":[]},{"id":"03a5f0701303bafd","type":"function","z":"b872cb4b.5a6448","name":"Generate Delated Messages","func":"if (msg.delay_time == undefined)\n    msg.delay_time = 4000;\nvar delay_time = msg.delay_time;\nif (msg.sunset == undefined)\n    msg.sunset = \"196,10,0\";\nvar sunset = msg.sunset;\n\nsendLater(0, msg, \"rgb,0,\" + sunset);\nsendLater(delay_time * 1, msg, \"rgb,1,\" + sunset);\nsendLater(delay_time * 2, msg, \"rgb,1,\" + sunset);\nsendLater(delay_time * 3, msg, \"rgb,2,\" + sunset);\nif (msg.existing[0] == undefined) {\n    msg.existing[0] = \"0,0,0\";\n}\nsendLater(delay_time * 4, msg, \"rgb,0,\" + msg.existing[0]);\nsendLater(delay_time * 5, msg, \"rgb,3,\" + sunset);\nif (msg.existing[1] == undefined) {\n    msg.existing[1] = \"0,0,0\";\n}\nsendLater(delay_time * 6, msg, \"rgb,1,\" + msg.existing[1]);\nsendLater(delay_time * 7, msg, \"rgb,4,\" + sunset);\nif (msg.existing[2] == undefined) {\n    msg.existing[2] = \"0,0,0\";\n}\nsendLater(delay_time * 8, msg, \"rgb,2,\" + msg.existing[2]);\nsendLater(delay_time * 9, msg, \"rgb,5,\" + sunset);\nif (msg.existing[3] == undefined) {\n    msg.existing[3] = \"0,0,0\";\n}\nsendLater(delay_time * 10, msg, \"rgb,3,\" + msg.existing[3]);\nsendLater(delay_time * 11, msg, \"rgb,6,\" + sunset);\nif (msg.existing[4] == undefined) {\n    msg.existing[4] = \"0,0,0\";\n}\nsendLater(delay_time * 12, msg, \"rgb,4,\" + msg.existing[4]);\nsendLater(delay_time * 13, msg, \"rgb,7,\" + sunset);\n\nif (msg.existing[5] == undefined) {\n    msg.existing[5] = \"0,0,0\";\n}\nsendLater(delay_time * 14, msg, \"rgb,5,\" + msg.existing[5]);\nif (msg.existing[6] == undefined) {\n    msg.existing[6] = \"0,0,0\";\n}\nsendLater(delay_time * 15, msg, \"rgb,6,\" + msg.existing[6]);\n\nif (msg.existing[7] == undefined) {\n    msg.existing[7] = \"0,0,0\";\n}\nsendLater(delay_time * 16, msg, \"rgb,7,\" + msg.existing[7]);\n\n/**\n* @param {number} delayMS\n* @param {NodeMessage} msg\n* @param {string} payload\n*/\nfunction sendLater(delayMS, msg, payload) {\n    node.warn(`In sendLater(${delayMS},${msg},${payload}) - setting up a timer to send payload '${payload}' in ${(delayMS/1000).toFixed(2)} seconds time`)\n    const callback = function (msg, payload) {\n        node.warn(\"Sending delayed payload \" + payload);\n        msg.payload = payload;\n        node.send(msg);\n    }\n    setTimeout(callback, delayMS, RED.util.cloneMessage(msg), payload)\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1740,"y":340,"wires":[["56e2873e77a8f625"]]}]

I may have messed up your messages but the spaced out delay works. In essence, call the function sendLater with a delay time, a msg and a payload - it will "send it later"

1 Like

I think it may be necessary to clone msg inside the function, otherwise all the changes that are made to msg at the top level will be made before the delayed messages are sent. Since parameters are passed by reference all the function instances will be accessing the same msg.

Agreed. (its there in the function at bottom of code) setTimeout(callback, delayMS, RED.util.cloneMessage(msg), payload)

Oops yes, I missed it. I suppose because my instinct would have been to put it at the start of the function, for no particular reason.

Thanks.

I think that wasn't helping me either.

When I was programming in my formative years it was in BASIC and that was a bit of a dog's breakfast language, but it was what I had.

That the call to the function is written BELOW the function in these cases really throws me.

I'm looking at it now and shall study what you did.

Thanks @Steve-Mcl for the code.
If you goofed with the messages being sent, not a big deal.
I'm sure (or: I hope) I can work that part out.

What goof?

He said

All is good.
Though I did see/find an extra line in there for led1 being turned on twice.
But that isn't a problem.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.