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"