Tracking recently changed events?

Hi, I've recently moved from Hubitat's Rule Machine to node red and am having a ball with it. I was able to replace a number of my simple rules to node red flows, but I'm stuck with some flows that require looking at things that have recently changed.

This is an example of what I'm trying to do.

I'd like to make a flow that captures an image of my front porch when the screen door is opened, but I don't necessarily need a picture of me when I just arrive home and open the screen door. In rule machine, I set up a "recentpresent" variable that tracks if I've been present for less than 3 minutes. When the screen door opens, it firsts checks if recentpresent is yes or no. If recentpresent shows yes, then the screen door opening won't trigger the image capture. Many of my rules in rule machine depend on recently changed events, but I'm just not sure how to accomplish something similar in node red.

Any help would be appreciated!

Thank you!

I'm probably missing some subtlety but I would look at the trigger node as a good starting point and maybe the simple gate node - https://flows.nodered.org/node/node-red-contrib-simple-gate

Does Hubitat expose the recentpresent info to Node-RED or is the problem perhaps figuring out the equivalent in Node-RED? (I do not know the logic used by Hubitat to maintain the value).

Thank you! I was finally able to get this to work with these two nodes.

I couldn't figure out how to connect a switch to a payload that is changed by node red. The trigger node did that for me.

I thought maybe I could get the rest of the flow to work without simple gate, but I don't really know how to get "if both conditions are true then continue". Simple Gate allowed me to close the flow until my presence is no longer "recent" which works well.

My next confusion is how do I make the payload from this trigger available to all my flows?

... just wire it up ?
Maybe using link nodes if you need to cross tabs.

if i understand you correctly then the answer is much easier than the route you seem to be suggesting. The simplest way is to create 2 switch nodes in series with outputs set for true for each of your conditions. If you need to carry on your flow for the false conditions you may do so within each switch node. If you dont need anything for false then just dont enter them into the switch parameters.
Another method is using the function node and writing some javascript code to route your message to your defined outputs using var msg conditions. The node-red help has very good information and example code to do this.
Node red was new to me a few weeks ago. I have surprised myself how quickly i picked it up. It is due to the fantastic software node-red is and the help from this forum which has been so far accurate, friendly and polite. Unlike all my other experiences with internet forums.
Smart home automation is actually possible due to node-reds ability to communicate with virtually every device.

1 Like

In hubitat's rule machine, I have created a rule that sets a global variable that is available to all rules. Basically when someone becomes present it changes the recent present variable for that person to true. After 5 minutes, it changes the recent present to false.

Then with another rule that handles screen door actions, it checks if the recentpresent is true or not first. If it's true, then go ahead and go to the next condition or action. If it's false, then exit the rule.

I want to make something equivalent to that in node red. Trigger helps me with the variable part. When a person becomes present it triggers a payload of 1, then after 5 minutes the payload changes to 0. With the gate node, payload of 1 closes the gate. Payload of 0 opens the gate.

I'm having trouble getting this to work with 2 switches in series. Say I make the first switch for the screen door contact sensor. If true then go to the next step. Then the next switch is for the recent present trigger. Nothing seems to pass through that step unless the recent present trigger is triggered. Once the trigger's wait for time completes, then the rest of flow will proceed. For the most part the recentpresent will be false, so I was hoping it would just pass through this switch.

Node red has definitely been the most fun and is the slickest out of the ones I've tried. When I used SmartThings, I did everything with webcore. It's like node red in that you can copy and distribute pistons. Copy and paste parts of rules. And is drag and drop. Then when I switched to Hubitat, I had to get used to Rule Machine. It is much clunkier and seems to take much longer to create a rule.

Off topic, but one thing I found cool with a node red node is when doing http requests to my ip camera, most other rule engines would have you pass the id and password through the url, but the http request node has a field for basic authentication.

hi, I am not familiar with the recent present trigger. Using switches in series due to the nature of how node red processes messages, you must remember that switch passes the whole message through the output if the function has been satisfied. Messages that are not satisfied are not forwarded to the next process. (unless another output is set for "otherwise" in the switch parameters) The order of 2 or more switch nodes does not matter for simple ='s and otherwise parameters.
If in doubt put an inject node at the beginning of the flow and put debug nodes after each switch to analyse your message outputs at each stage from a manually sent trigger.
If you still struggling export the flow on here with the ```` at start and end of code. I will have a look to see if i can understand what your trying to accomplish and then edit your flow accordingly.

debounce node is the way to go. Add the node through palette manager. Debounce only lets a message through if the sensor has not reported a message (with the parameters satisfied) for a length of time you specify.

I ended up using node-red-contrib-bool-gate node to do what I needed along with the builtin trigger code.

My real flow is slightly more involved and I needed something that will allow me to use "and" and "or" logic. So in my example, I want my front door camera to take a picture when someone opens the screen door. But there are some situations I don't want it to take a picture. A) If anyone has been present for less than 5 minutes (meaning anyone who just got home and is most likely the person to open the screen door) B) if someone opens the inside door first (meaning if I am inside and open the front door before opening the screen door, I don't want it to take a picture).

In my flow I have an "or gate" node which monitors the recent presence along with monitoring whether the front door is open. If one person is recently present or inside door is open, then false and the flow won't happen. A second "and gate" monitors that the "or gate" is true and also that the screen door opens.

These feels complicated but any other solution feels more complicated to me.

What I find confusing is that I thought there was some kind of out of the box solution for checking multiple conditions with and/or logic, but I'm having a hard time finding anyone talking about it in the forum. In fact, the bool gate node hasn't been updated for 3 years and 5 months.

Anyways... I made a very simple version of the two switches in series. Note, I did not include any of the recent presence stuff I was talking about earlier. Just two switches, if screen door opens then go to the next device, if the "Me" device is present, then turn on living room light.

The problem I'm running into is that if the "Me" device becomes present, it will kick off the rest of the flow despite the first switch, the screen door, not opening. It doesn't care about what happens before it. Honestly, this does seem like the expected result. So I'm most likely doing it wrong.

[{"id":"d6e1db92.b81498","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"9671994c.3243b","type":"hubitat device","z":"d6e1db92.b81498","name":"Screen Door","server":"559b622a.b9923c","deviceId":"385","attribute":"contact","sendEvent":true,"x":70,"y":120,"wires":[["2131c6f7.d418d2"]]},{"id":"2131c6f7.d418d2","type":"switch","z":"d6e1db92.b81498","name":"","property":"payload.value","propertyType":"msg","rules":[{"t":"eq","v":"open","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":210,"y":120,"wires":[["c62e46ba.392128"]]},{"id":"c62e46ba.392128","type":"hubitat device","z":"d6e1db92.b81498","name":"Me","server":"559b622a.b9923c","deviceId":"839","attribute":"presence","sendEvent":true,"x":350,"y":120,"wires":[["aa227e29.587e8"]]},{"id":"aa227e29.587e8","type":"switch","z":"d6e1db92.b81498","name":"","property":"payload.value","propertyType":"msg","rules":[{"t":"eq","v":"present","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":500,"y":120,"wires":[["393d99c5.71aaa6"]]},{"id":"393d99c5.71aaa6","type":"hubitat command","z":"d6e1db92.b81498","name":"Living Light","server":"559b622a.b9923c","deviceId":"164","command":"on","commandArgs":"","x":650,"y":120,"wires":[[]]},{"id":"559b622a.b9923c","type":"hubitat config","z":"","name":"Hubitat","usetls":false,"host":"10.0.1.150","port":"80","appId":"1473","nodeRedServer":"http://10.0.1.5:1880","webhookPath":"/hubitat/webhook_","autoRefresh":true,"useWebsocket":false}]

I think this is mainly an approach issue. Because Node-RED is message based (flow-based) and asynchronous in nature, each node only allows a single input. So boolean logic has to have all inputs in the same message, or have some inputs in a stored variable and the rest in the msg or have some kind of specialist gate node or similar.

In most cases, the switch node is sufficient as has been mentioned and if not, many people will switch straight to using a function node and write the custom logic in JavaScript. Either way, people talk less about boolean gate logic than in more functionally-based tools. Because there is much less need.

Thank you for your input. I'm still trying to wrap my head around how to approach flows like this one.

Unfortunately, I feel more lost than when I started. Does no one need to make flows where they need to make sure two conditions are true at the same time before continuing with the flow? And if they do, what does the flow look like? I can't seem to get two switches in a series to replicate this.

Thank you!

Of course, at least I do, I have maybe missed or simply skipped some possibilities to use several nodes, I solve most of such needs with code in function nodes and context variables (flow or global if I need to make them available to all tabs). Some people say such a setup can be difficult to maintain in the long term but so far I have had no problems even looking up code I wrote years ago. Besides NR has also improved with built in tools and features that makes life easier from this point. So in this way I build my conditions. I can look into some of my "logic gates" and giva a simple example if you are interested

Yes, thank you. I'd be very interested.

I've been trying to figure out global variables also. Earlier in the thread, @dceejay had suggested using link nodes which I have started using. I'm not sure what best practices are, but I've created a tab filled with all of my devices that have triggers that I use for my recentpresent, recent opened, etc. I added link out to the end of those. Then when I have a flow that needs to know if something was recently opened, I link it in the with the bool gate.

I'm probably not doing it right, but these flows are noticeably more responsive than anything I made in webcore (smartthings) or rulemachine (hubitat). My guess iss my webcore pistons and rulemachine rules weren't the best either. hah.

I think if i understand what you are saying correctly you have not taken into account that a single message can be diverted in different directions from the node output. So the same message is diverted in 2 directions or more. The message still has the same msg id but is forked and goes in 2 or more directions from 1 input. If a delay or rate monitor node is applied to 1 of the directions with a debounce you can stop the flow continuing after a period of time or until a number of messages is received while the other fork from the message can carry on processing the message and performing other functions.

@robmak unfortunately I've gone off topic. @dceejay's suggestion of using the trigger node worked for me. But probably because I'm using the bool gate for the rest of my flow. I would guess debounce would have also worked for me.

I just need to see one example of how something like "if one of these 5 things is true, then it is true" like you'd see with "or" logic but in typical switch based node red flow.

I think in a real world (my world) I have certain STATES. Like the sun is up or down, my home alarm system is armed or unarmed, my wife is not home, it's Monday etc etc. Those states will change and when they do you will receive an EVENT or message about it. But what if you need the that information in between the events, what to do? You need the state information.

In one way or another, you need to keep the state information for certain variables. One convenient way is to use context that is available in NR. If you have states that all your tabs, the complete flow needs information about, you use global.set("recentpresent", true), if it is just on one single tab, use flow.set("recentpresent", false) and if it is just for a single node, use context.set("recentpresent", true) when they change state. In this way you have the states of required variables always available and you can easily use them in your flow. Also in most nodes

As example, I have a simple headlight I want to turn on if an intruder gets detected. But only if sun is down and our home alarm system is armed. So a simple solution would then be to use flow or global context variables. Either using nodes or a function node

In this case, using a function node. Is really easy to add further states for the condition. Messages are blocked until the required variables states are set so the condition is fulfilled

Or using standard nodes like this

I think is a matter of taste. Keeping state information in context works fine I think, it's fast since it is in memory

EDIT: If it's enough if one of the states is true, use || instead of &&. Standard javascript...

Thank you for this! This is exactly the type of thing I'm trying to do. I thought others would be also but I guess home automation wasn't really node red's target audience. Or was it? I have no idea.

My flows were starting to look like this:


Visually, they make sense to me, but feel bloated since I've been told that's not the way node red was meant to be used.

Your function has less characters than all the fields I had to fill in to get bool gate to work. I'm trying to use as few extra nodes as I can, so hopefully I can shave a few milliseconds off my flows using the function node and context.

One more thing to say about using context. If you have many states to keep track of (like I have) it might be more convenient to use an object in context. To make state information survive a restart, it's also possible to keep context persistent, it's described in NR documentation "how to". Some users would use a plain text file in the file system or a database

As example, assume you have an object "myStates" in context keeping all your various states. The following simplified code in a function node and flow demonstrates how easy you can update and get access to the properties

When your home alarm system changes the arm state (simulated with the buttons) you can see how the corresponding property is changed. Wherever in your flow you need that state information you can easily grab it (using global.MyStates.armed in node configurations and global.get("MyStates.armed") in function nodes)

global.set("myStates", {"armed":true, "sunDown": false, "sunUp":true, "recentpresent":false});
//the home alarm system changed state, update the corresponding property
global.set("myStates.armed", msg.payload);
//grab the complete MyStates object and send it out to view it
msg.payload = global.get("myStates");
return msg;