Help with structuring if/then logic in NR

I'm very familiar with Node Red and have made lots of flows but for some reason my brain is tanking on constructing a particular flow and wanted to see if anyone had any idea how to construct it.

Here's the issue and then I'll tell you what I'm trying to do. I have a flow set up that does one thing: if it's a normal night (home before 10:30pm), do X (turn these lights on, those off, etc.); if it's a late night (after 10:30pm AND outside my home location) then do a different series of things once I return to my home. The flow works great and has for years - my phone reports location data to NR and combines that with geofencing and a timestamp to turn lights etc. on/off at the proper time. This is not what I need help with.

The issue is that sometimes my phone sends bad data and misreports my location to NR, meaning I've had my lights turn on at 2am because the phone incorrectly tells NR I'm out and NR responds by doing exactly what I told it to do when I'm out late. So what I'm trying to do is overcome the occsaionsal bad data issue since clearly my bedroom lights turning on randomly at 2am is not ideal!

The problem is that the phone query can only go as a push FROM the phone TO NR and not the other way around. This is a limitation of the way my phone reports location data and nothing I can change or fix that I'm aware of. The phone sends the location data every 2 minutes.

So the logic I'm trying to do and where my brain seems to be falling apart :slight_smile: is this: if it's 10:30pm and the last thing NR "heard" from my phone is that I'm home, ignore everything from my phone for the next 8 hours.

In other words, if I'm home at 10:30pm, don't execute the "late night" flow for the next 8 hours no matter what the phone says about my location because my phone is lying! :slight_smile:

This would be so easy if I could have NR execute the query rather than be the passive recipient of a push since I could just tell NR that if I'm home at 10:30pm, stop querying the phone for 8 hours. Unfortunately, that's not possible.

The if/then essentially is: if time=22:30 and [variable globalhome]=true then... ignore everything my phone says for the next 8 hours.

It's that last part I'm struggling with. Any ideas? Thanks

Node-red could tell if your phone is connected to your WiFi (ping it) and set a global flag.
Then if (it's after 10:30 and phone is not on WiFi) etc

Hmm I seem to have not addressed the question you actually asked...

I need a bigger screen to keep it all within view!

A first attempt. I'm pretty sure it can be done much more elegantly!
This sets a variable to indicate if it's after 22:30 (and before 06:30)
Another variable to define if the normal or late night routine is appropriate.

[{"id":"63984354.c2adcc","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"9c6a3ba5.7f7cc8","type":"inject","z":"63984354.c2adcc","name":"22:30","props":[{"p":"payload"}],"repeat":"","crontab":"30 22 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"NIGHT","payloadType":"str","x":120,"y":80,"wires":[["7e567988.1c79f"]]},{"id":"7e567988.1c79f","type":"trigger","z":"63984354.c2adcc","name":"","op1":"","op2":"DAY","op1type":"pay","op2type":"str","duration":"8","extend":false,"overrideDelay":false,"units":"hr","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":300,"y":80,"wires":[["c2a52afa.382ca8"]]},{"id":"c2a52afa.382ca8","type":"change","z":"63984354.c2adcc","name":"","rules":[{"t":"set","p":"nighttime","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":80,"wires":[["f27fc35e.e7d728"]]},{"id":"81f4fb9e.0d802","type":"comment","z":"63984354.c2adcc","name":"Set flow.nighttime to NIGHT at 22:30 and DAY at 06:30","info":"","x":250,"y":40,"wires":[]},{"id":"1fbc230b.9c9b7d","type":"mqtt in","z":"63984354.c2adcc","name":"Phone location input","topic":"","qos":"2","datatype":"auto","broker":"b297f812.f52a8","nl":false,"rap":true,"rh":0,"x":130,"y":220,"wires":[["2511b89c.dc5a4"]]},{"id":"2511b89c.dc5a4","type":"function","z":"63984354.c2adcc","name":"Set normal or latenight routine","func":"if (msg.location == \"home\" && flow.get('nighttime') == \"DAY\") // or however you tell the location. //arrived home during daytime\n{\n    flow.set('routine', \"NORMAL\");\n}\n\nif (msg.location != \"home\" && flow.get('nighttime') == \"NIGHT\" && flow.get('routine') != \"NORMAL\") // did not get home during daytime\n{\n    flow.set('routine', \"LATENIGHT\");\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":220,"wires":[[]]},{"id":"fac6f848.e71c","type":"switch","z":"63984354.c2adcc","name":"Normal or  Latenight?","property":"routine","propertyType":"flow","rules":[{"t":"eq","v":"NORMAL","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":580,"y":340,"wires":[["fc9615f4.74b08"],["a55b8528.0a5a4"]]},{"id":"fc9615f4.74b08","type":"function","z":"63984354.c2adcc","name":"Normal nighttime routine","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":830,"y":320,"wires":[[]]},{"id":"a55b8528.0a5a4","type":"function","z":"63984354.c2adcc","name":"Late night routine","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":810,"y":360,"wires":[[]]},{"id":"f27fc35e.e7d728","type":"switch","z":"63984354.c2adcc","name":"Only at 06:30","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"DAY","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":470,"y":120,"wires":[["5cd84e36.29e9e8"]]},{"id":"5cd84e36.29e9e8","type":"change","z":"63984354.c2adcc","name":"Reset flow.routine","rules":[{"t":"set","p":"routine","pt":"flow","to":"LATENIGHT","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":120,"wires":[[]]},{"id":"e1dd78a.4832488","type":"comment","z":"63984354.c2adcc","name":"Process phone location data","info":"","x":160,"y":180,"wires":[]},{"id":"dc9d3bea.96b4b8","type":"inject","z":"63984354.c2adcc","name":"Repeat as required","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":340,"wires":[["5d3e448e.d720a4"]]},{"id":"5d3e448e.d720a4","type":"switch","z":"63984354.c2adcc","name":"Is it nighttime?","property":"nighttime","propertyType":"flow","rules":[{"t":"eq","v":"NIGHT","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":360,"y":340,"wires":[["fac6f848.e71c"]]},{"id":"4eee9531.57611c","type":"comment","z":"63984354.c2adcc","name":"However you trigger night time switching etc","info":"","x":210,"y":300,"wires":[]},{"id":"b297f812.f52a8","type":"mqtt-broker","name":"MQTT","broker":"","port":"1883","clientid":"","usetls":false,"compatmode":false,"protocolVersion":4,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

Thanks, but unless I'm missing something,that still doesn't solve the main issue which is when the phone mistakenly reports that it's on latenight when in reality it's on normal.

If the phone reports itself as home before 22:30 it sets routine to "normal".
That variable only gets reset to "late night" at 06:30.

At least, that's what I intended!

Ah I see. I was trying to integrate your thoughts into the flow I already have so wasn't seeing it but think I do now. You're saying - and I'm writing this out here to make sure I understand so I can incorporate it into what I have:

  1. At 10:30pm check if the phone is home and, if it is, then set the "homeforthenight" variable to "true" which resets the next day.
  2. Before the flow is allowed to change the routine to "latenight" it hits a switch node first which checks whether the "homeforthenight" variable is true. If it's true, the message is dropped (since that means the phone made a mistake) and the flow never gets switched to "latenight"; otherwise it can go about the "latenight" routine since the phone is genuinely not at home.

Is that correct? If so, I think you nailed it, thanks!

That's pretty much it.
Because location reports are not 100% reliable, I thought any report of "I'm home" up to 22:30 should set the flag rather than exactly at 10:30.
But doing it like this, you would have to prevent the phone from triggering at breakfast time normal function for the next evening. I didn't include that.

You could do it with an inject at 5pm say.

Coming up with that normal vs latenight flow was actually pretty tricky not so much due to NR but because of figuring out what constitutes a "normal" night; I ultimately decided that "normal" meant "home before 10:30" which would include things like going out for dinner rather than "normal" meaning home the whole time. Thus I was adapting your basic idea to the way I defined "normal" and setting the flag at a specific cutoff time.

In case you're curious, it looks like this. The stuff offscreen is checking my phone location (or if it's connected to home wifi) and putting a timestamp on it which leads to the flow in the picture - along with your flow - looking at my phone's location and time and determining whether a night is normal or not. The night only becomes "latenight" if two conditions are met: my phone is in my local city area but NOT within 1/2 mile of home AND the timestamp of that location is between 10:25pm & 3am. If those conditions are met, latenight is triggered - only now I put your idea there as a double-check before triggering the late night events in case of a phone glitch.

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