Time delay with persistence?

Hi All

I'm upgrading my light scene controller to support being triggered by presence sensors. Eventually I will have about 12 lighting zones in the home, each with one or more presence sensors.

The idea is that when someone moves or makes noise, it will trigger one of the lighting scenes, and it will continue to stay on that scene until a preset time after there has been no additional movement or noise (i.e. extend the delay).

(FYI - an aside - I've been testing the audio sensor as a way of only extending - not actually triggering - the lights to come on, and it has been a bit of a revelation - it's a very reliable way of preventing that thing where you're dead still and the lights go off.)

So far I've used the Trigger node which is excellent, but I don't think this persists over re-deploy in Node-RED. This becomes more of a problem as I plan to play around with Node-RED a lot but also don't want to cast various rooms into darkness (or leave lights on, or do anything that changes other family members' expectations of the system...)

I envisage there could be 4 or 5 delays running at a time, determining the lighting in a room, and a single re-deploy of Node-RED would kill them all.

Is there some other way of using the delay node to allow it to continue "counting" even when I re-deploy? Or do I need to code some other kind of timer system, e.g. store timeouts in global context and then poll them every second then turn off the lights once current time is past the set time?

No - unless you only deploy modified nodes and dont modify the delay.

That is one way.

Another is to use cron-plus with Persist dynamic schedules ticked

[{"id":"1993bc5dc260aa6d","type":"function","z":"553814a2.1248ec","name":"","func":"var time = Date.now() + parseInt(msg.delay);\n\nvar dynPl = [\n    { \n        \"command\": \"add\",\n        \"topic\": msg.topic, \n        \"name\": msg.topic,\n        \"payloadType\": \"json\", \n        \"payload\": msg.payload, \n        \"limit\": null, \n        \"expressionType\": \"dates\", \n        \"expression\": time \n    },\n    {\n        \"command\": \"remove-inactive-dynamic\"\n    }\n]\nmsg.payload = dynPl;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1610,"y":100,"wires":[["acf947053c6bb7e4"]]},{"id":"c45244717b6f073e","type":"inject","z":"553814a2.1248ec","name":"2-sec-later","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"2000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"2-sec-later","payload":"{\"desc\":\"the payload to send in 2 second\"}","payloadType":"json","x":1440,"y":80,"wires":[["1993bc5dc260aa6d"]]},{"id":"acf947053c6bb7e4","type":"cronplus","z":"553814a2.1248ec","name":"","outputField":"payload","timeZone":"","persistDynamic":true,"commandResponseMsgOutput":"output2","outputs":2,"options":[],"x":1760,"y":100,"wires":[["365e4ea3ea87acfd"],[]]},{"id":"4606e572ad7eb9e5","type":"inject","z":"553814a2.1248ec","name":"4-sec-later","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"4000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"4-sec-later","payload":"{\"desc\":\"the payload to send in 4 second\"}","payloadType":"json","x":1440,"y":120,"wires":[["1993bc5dc260aa6d"]]},{"id":"365e4ea3ea87acfd","type":"debug","z":"553814a2.1248ec","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload.desc","targetType":"msg","statusVal":"payload","statusType":"auto","x":1950,"y":100,"wires":[]}]

fnuj8aueh5

2 Likes

I've been away and not programming for a long time.

Ok, so if I am understanding what you say:

The system is at normal and the lights are what ever.

Someone trips/triggers a sensor and the scheme is set to in attendance - to call it.

If no further trigger happens after time x, the lights are put back to what ever.

But if movement is detected (or sound as you imply) they continue as set.

So why not have a trigger node set that if another message is received: extend time?

Just a thought.

@hazymat. This sensor will detect people even if they are sleeping. It's expensive, and out of stock at the moment.
I have a PIR sensor for the lights in the kitchen which works well while you move a lot, but as soon as you do minimal movement tasks it inevitably times out. I also tried a radar sensor, but that would false trigger so much it was a waste of time. I will give this a try as soon as it is back in stock.

1 Like

Cute!

I would nearly like to get one to just play with. But I've been told not to play with things too much. I may go blind! :wink:

That looks very interesting. Expensive yes, although still a quarter of the price of some consumer / commercial packaged multisensors (e.g. zigbee, z-wave etc.)

If you like to make your own sensors (as I do) then I can highly recommend audio presence sensing as it just works. I have been using the MAX9814 module powered from 5V, with a simple RC circuit to convert the signal to an audio envelope, then feeding that into an arduino or ESP8266. Biggest trouble I found was finding an amplifier module with low enough noise to allow sensing really low level sounds (e.g. clicking a finger very softly at the other side of the room) but this one does the job. I have combined it with a timeout of 5 minutes which works well for kitchen (i.e. it NEVER goes off when you are in there) and a timeout of 30 seconds for bedroom whilst sleeping (i.e. to cover getting up to go to the loo). With the bedtime setting I have turned OFF the audio as a means of initially triggering, so that movement is required to trigger but turned ON the audio as a means of extending, i.e. so if you are chatting after moving then it stays on. This prevents it randomly coming on in the middle of the night.

1 Like

The triggering / extending isn't the problem here... that works nicely. The issue is persisting that trigger across Node-RED re-deploys...

Oh.... Ok.

(Dumb question)

So during an invocation of one of these triggers (time periods) NR is redeployed?

Yes?

That's the use case I am trying to deal with, yes. Imagine me sitting in my room coding something up / tinkering with Node-RED, and someone else in the home going to bed, expecting the lights to turn off automatically in 5 minutes, but they never do, because the Trigger node was reset due to a Node-RED redeploy!

Thanks for this tip Steve, I think cron-plus might do the job nicely. I hadn't heard of it until now!

Depending how your flows are setup, you could try the Stop Timer Vari-Delay mode which does persist across a reboot/redeploy.

1 Like

Cron+ is my No1 timer node!, but node-red-contrib-stoptimer-varidelay is a great alternative for applications such as yours, and worth looking at, especially because it is so simple to setup.

Thanks for the comments. In the end I coded my own somewhat lame, but adaptable, cron system using timestamps stored in global context and an inject node. It doesn't work to millisecond accuracy, but it's only used for doing certain things after a timeout (e.g. turning off lights). All the things that require immediate actions (e.g. turning on lights) happen in response to normal message flow in Node-RED.

The reason: I wanted to store certain timestamps in objects I have already set up in global context, as I'm consolidating as much as I can about state management in those objects so it makes sense to use them for timekeeping as well.

I am probably way too new to fully understand, let alone interject... but can you not have a 2nd instance of Node-Red running on the same "server"?... one to play around with and the other to run the place.

Then just pass on the updated flows at a more convenient time.

That would be far too well organised for me :slight_smile: It's a sensible idea. I guess the only counter-argument is that it's very useful to be able to build stuff with real-world actuators doing things around you (however annoying for the family members who have to put up with things changing...)

Of course it's possible to simulate them with LEDs etc... but nothing beats being able to tinker with something when it's live / in production. One of those things we don't get to do at work, so it's fun to do it at home...

1 Like

Just turn everything off when the flow starts up.
If someone is present they will retrigger the sensors. And the lights going out will tell everyone that hazymat is tinkering again!

1 Like

Can I mark that one as the solution? :stuck_out_tongue:

1 Like

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