Hi,
I have a function node with a loop in it, it generates random time delays.
I want it to auto star when the PI reboots or when the flow gets re-deployed.
Is the below correct? From my function node.
const minDelay = 1, maxDelay =5; // seconds
var a = 1;
loop();
msg.payload = a;
function loop() {
if (a==1) {
node.send(msgToSend);
msgToSend = msg;
let delay = Math.random() * (maxDelay - minDelay) + minDelay;
setTimeout(loop,1000 * delay);
node.status({fill:'green',text:delay.toFixed(2)});
}
}
When posting code, click the button that looks like </>
at the top.
I see you tried, but.....
Ok, break down:
msg.payload = a;
Wrong way around - I think.
You want a
to be the payload
.
So it should be:
a = msg.payload
In your loop:
You only have testing for a == 1
What if it is another value?
Reading your original code again where: msg.payload = a
:
So a will always be 1.
Why test at all?
Thank for the reply.
I want the payload to be one always.
Debug - error message
21/04/2020, 09:12:57node: d5575e9b.cc1ac
function : (error)
"ReferenceError: msgToSend is not defined"
I have taken the test out.
const minDelay = 1, maxDelay =5; // seconds
var a = 1;
loop();
msg.payload = a;
function loop() {
node.send(msgToSend);
msgToSend = msg;
let delay = Math.random() * (maxDelay - minDelay) + minDelay;
setTimeout(loop,1000 * delay);
node.status({fill:'green',text:delay.toFixed(2)});
}
I think you have exceeded my skills sorry.
Whichever way you do it - you will need an inject (on start) node in front to trigger it to start running on boot.
Thank you for the reply-
I have put a inject node in front of it injecting 1 on at 0.1, but it still don't start.
Colin
21 April 2020 08:13
7
ScheepersJohan:
node.send(msgToSend);
As the error says, you have not defined msgToSend, you need var msgToSend = something
somewhere before it is used. Alternatively perhaps you just need to change all uses of msgToSend
to msg
if it is actually a copy of the original msg that you want to send each time.
Thank you @Colin , solved.
These two wrong way around
node.send(msgToSend);
msgToSend = msg;
Correct is way
msgToSend = msg;
node.send(msgToSend);
Or just
node.send(msg);
Can you have a var in setTimeout(loop,1000 * delay); instead of "delay"?
What do you mean? delay
already is a variable.
Thanks for your response
Meant something link this:
msg.payload = a;
loop();
function loop() {
msg.paload = 1;
node.send(msg);
let delay1 = 10;
setTimeout(loop,1000 * delay1);
node.status({fill:'green',text:delay1.toFixed(2)});
msg.paload = 0;
node.send(msg);
let delay2 = 5;
setTimeout(loop,delay2);
node.status({fill:'green',text:delay2.toFixed(2)});
}
Can you describe what you mean. From that code, I'm really not sure what you intend.
send msg.payload =1 wait delay1 seconds and then send msg .payload = 0 wait delay2 seconds
send msg.payload =1 wait delay1 seconds and then send msg .payload = 0 wait delay2 seconds and then the first msg
This node will have a interrupt statement in it
var run = context.get('state') || false;
if (msg.topic.toLowerCase() === 'control') {
run = ! run;
}
context.set('state',run);
node.status({fill:(run) ? 'green':'red'});
var msgToSend = null;
loop();
return null;
loop();
function loop() {
msg.paload = 1;
node.send(msg);
let delay1 = flow.get("ontime");
setTimeout(loop,1000 * delay1);
node.status({fill:'green',text:delay.toFixed(2)});
msg.paload = 0;
node.send(msg);
let delay2 = flow.get("offtime");
setTimeout(loop,1000 * delay2);
node.status({fill:'green',text:delay.toFixed(2)});
}
ScheepersJohan:
msg.paload = 1;
don't you mean payload
instead of paload
?
Sorry Yes
var run = context.get('state') || false;
if (msg.topic.toLowerCase() === 'control') {
run = ! run;
}
context.set('state',run);
node.status({fill:(run) ? 'green':'red'});
var msgToSend = null;
loop();
return null;
loop();
function loop() {
msg.payload = 1;
node.send(msg);
let delay1 = flow.get("ontime");
setTimeout(loop,1000 * delay1);
node.status({fill:'green',text:delay.toFixed(2)});
msg.payload = 0;
node.send(msg);
let delay2 = flow.get("offtime");
setTimeout(loop,1000 * delay2);
node.status({fill:'green',text:delay.toFixed(2)});
}
@Colin This is what I want to achieve , I don't know what standard node I can use, as we suffer from a lot of power outages and most timing nodes don't give you a output once the on time are pass or you cant set the day off week from a message input.
If you have a idea I can use I will appreciate.
The code in the above is for the Pump control
Colin
21 April 2020 21:07
21
I think probably the easiest way is with a function node.
There are a couple of issues with your code.
I don't know what the var msgToSend line is doing, nor the loop() function after the return null.
You appear to be setting up two timers, I don't think you want to do that, you just want one, with the delay time alternating between the the two values.