Only pass True if input is true for X seconds

Hey all,
I'm relatively new to NR, but absolutely LOVING it.

I'm working on a flow which will let me know if a cupboard has been left open. The input is a reed switch connected to a RPi GPIO pin (this is working), the output is an email node (this is also working).
What I'm unsure how to achieve is the bit in the middle.

Basically, I only want to pass a trigger to the email node if the switch contact is open for 60 seconds.
I thought I could maybe use a 60 second delay and an AND node, but I'm not sure it works since the GPIO signal is continuously 1 or 0, as opposed to discrete, timed pulses.
I also tried node-red-contrib-timeframerlt, but found a similar problem (it will pass a signal after it is received x times in x seconds, but, again, it needs discrete pulses to work.)
I thought that maybe there is a way to use the trigger node to generate a True signal every 1 second that the input is held as True, but I'm not sure sure that's the best solution.

Could someone please point me in the direction of the right node I should be using for this?

I also found that the inject node works as a single pulse (ie you can't hold it down to transmit a continuous True/False signal), so I can't really test this without using the actual GPIO input.

  1. A side question: Is it detrimental in any way (performance/etc) to have a lot of nodes installed, but not in use?

Thank you for reading this far!

All the best,
Dax.

I'm stuck on this.

This too sorry.

This is also unclear what it has to do with things in the scheme of things.

I was going to say what I understand of the post, but it is not clear.

Can you try again please?

Hey Andrew, thanks for your reply.

Reed switch is connected to 5+ volts and the other contact is connected to RPi GPIO pin set to digital input.

The RPi GPIO node outputs a continuous 0 or 1 depending on the state of the reed switch.

I want to trigger an email node only when the state is continuously 1 (true) for 60 seconds.

I hope that's a bit clearer.

All the best,
Dax.

Thanks.

So where does the "clipboard open" come into the equation?

Just while I'm thinking about it, here's some thoughts:

But that is the same as the GPIO input really.

Though there is a constant signal on the pin, it only sends what it sees at any time.
(I think that is called differentiation - only showing differences.)

So the inject node could be used.

It sends a 1 or a 0 and that signal remains the last thing seen at the next node's input.
If the GPIO pin changes, it is like you pressing the inject node to inject the 0 or 1.

Anyway, I'll have a play and see if I can get what you want done.

This may work.

[{"id":"acb06eb6.909ce8","type":"inject","z":"7879609.4fb06a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":190,"y":1340,"wires":[["bb20a44d.c9f058"]]},{"id":"6b5b46f4.7044f8","type":"inject","z":"7879609.4fb06a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":190,"y":1380,"wires":[["bb20a44d.c9f058"]]},{"id":"cb76444b.c3b72","type":"trigger","z":"7879609.4fb06a","name":"","op1":"","op2":"ATTENTION!","op1type":"nul","op2type":"str","duration":"5","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":590,"y":1380,"wires":[["25c6644d.349384"]]},{"id":"25c6644d.349384","type":"debug","z":"7879609.4fb06a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":780,"y":1380,"wires":[]},{"id":"25c420fe.7308e8","type":"change","z":"7879609.4fb06a","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":660,"y":1340,"wires":[["cb76444b.c3b72"]]},{"id":"bb20a44d.c9f058","type":"function","z":"7879609.4fb06a","name":"GPIO pin input","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":380,"y":1380,"wires":[["cb76444b.c3b72","3b829652.5b3b0a"]]},{"id":"3b829652.5b3b0a","type":"switch","z":"7879609.4fb06a","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":545,"y":1340,"wires":[["25c420fe.7308e8"]],"l":false}]

Clipboard? Oh, cupboard! There is a door on a cupboard which has a reed switch and magnet pair mounted on it.

Silly me. I can't read.

Thanks, I'll try your flow in the morning.

All the best,
Dax.


Try this -

Set a trigger node as above when it gets a payload of 1 the 60 sec timer starts, if no new message arrives it sends an output to trigger your email, if a zero is received the timer is reset and nothing is sent.

1 Like

That's pretty much what I did in my bit of code - probably because I missed that extra reset option.

Well done.

Thanks so much smcgann99, I'll try that, too.

Cheers both!

I tried smcgann99's suggestion and it half works correctly.

  1. A trigger is sent even if the door is open for <60 secs (I've actually made it 2 secs now for testing).

  2. A trigger is sent when it is opened and another when it is closed. What's the best way to filter out the closed trigger? I had a thought to use an IF statement (since I also need to invert the sensor's output because I wired it as normally-closed which will trigger if the wire is cut.)

var DoorReed = msg.payload;
if (DoorReed == 0) {
  DoorReed = 1;
}
return msg;

I'm just getting started on my journey with NR, so any help would be appreciated.

All the best,
Dax.

If you set the reset correctly then it won’t send anything for that

Thanks dceejay,
What would be the correct setting, please?

Thank you,
Dax.

Whatever matches what the door sends for closed. 0 I think from looking at what you have

Okay, I got it solved. Thank you everyone for your help!

I had used a logic invert node that I found in the palette manager. It was happy to take 0/1 as input, but was outputting true/false. The Trigger node doesn't seem to like that and so it didn't respond the way I had expected. Using the invert code I wrote below, I've got it all solved!

if (msg.payload == 0) {
  msg.payload = 1;
} else {
  msg.payload = 0;
}
return msg;

By the way, what would be the easiest way to package this function into an invert node that I could make available to the public?

All the best,
Dax.

Why didn't you just start the trigger with a 0, and use the 1 to reset, instead of using code to invert it?

Hi Paul-Reed, because no-one suggested it and I'm a noob. :slight_smile:

Why doesn't a baby know the alphabet? :wink:

I'm going to look for some in-depth tutorial videos on NR. It's so wonderfully powerful and I've only just begun to scratch the surface of what's possible.

Side question: Is it detrimental in any way (performance/etc) to have a lot of nodes installed, but not in use?

All the best,
Dax.

It depends what you mean by lots of nodes. You would need to have LOTS of nodes for it to impact on performance. I wouldn't worry.
I occasionally have a palette clean-up and get rid of unused nodes, just to make it easier to find nodes when I'm building a flow. I can always add them again if I need them.

1 Like