Node-Red Flow Samples/Sharing

I don't remember if it was here or elsewhere, but I saw something on these forums about setting the porch light to a different color for the holiday season.

I wanted a routine to set the color to red/green every 15 minutes, and to switch between the two of them. I set a boolean in the flow representing the color, and switch between red and green. I also wanted it to behave during the night so it's not too flashy all night long. The rest of the night the bulb gets its color assigned elsewhere.

Here's what I came up with. Enjoy!

[{"id":"b8dd13b1.797cb","type":"change","z":"f9337f21.0eab78","name":"Turn Off","rules":[{"t":"set","p":"command","pt":"msg","to":"off","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":2380,"wires":[["89753df20ca7d578"]]},{"id":"5c9841f.19b74c","type":"change","z":"f9337f21.0eab78","name":"Turn On","rules":[{"t":"set","p":"command","pt":"msg","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":2340,"wires":[["89753df20ca7d578"]]},{"id":"1fbcdc78.00e81c","type":"comment","z":"f9337f21.0eab78","name":"Porch light","info":"","x":100,"y":2140,"wires":[]},{"id":"30aade80.91cb42","type":"within-time-switch","z":"f9337f21.0eab78","name":"sunset - sunrise","positionConfig":"96c207ac.2237a8","startTime":"sunsetEnd","startTimeType":"pdsTime","startOffset":0,"startOffsetType":"none","startOffsetMultiplier":60000,"endTime":"sunriseStart","endTimeType":"pdsTime","endOffset":0,"endOffsetType":"none","endOffsetMultiplier":60000,"timeRestrictions":"","timeRestrictionsType":"none","timeDays":"*","timeOnlyOddDays":false,"timeOnlyEvenDays":false,"timeOnlyOddWeeks":false,"timeOnlyEvenWeeks":false,"timeMonths":"*","timedatestart":"","timedateend":"","propertyStart":"","propertyStartType":"none","propertyStartCompare":"true","propertyStartThreshold":"","propertyStartThresholdType":"num","startTimeAlt":"","startTimeAltType":"entered","startOffsetAlt":0,"startOffsetAltType":"none","startOffsetAltMultiplier":60000,"propertyEnd":"","propertyEndType":"none","propertyEndCompare":"true","propertyEndThreshold":"","propertyEndThresholdType":"num","endTimeAlt":"","endTimeAltType":"entered","endOffsetAlt":0,"endOffsetAltType":"none","endOffsetAltMultiplier":60000,"withinTimeValue":"","withinTimeValueType":"msgInput","outOfTimeValue":"","outOfTimeValueType":"msgInput","tsCompare":"0","x":240,"y":2360,"wires":[["5c9841f.19b74c"],["b8dd13b1.797cb"]]},{"id":"76fddf4.66e0da","type":"inject","z":"f9337f21.0eab78","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":95,"y":2360,"wires":[["30aade80.91cb42"]],"l":false},{"id":"89ce2107.6a1858","type":"link in","z":"f9337f21.0eab78","name":"","links":["2837495c.ae2176"],"x":235,"y":2320,"wires":[["5c9841f.19b74c"]]},{"id":"35f56d8f.e1d64a","type":"link in","z":"f9337f21.0eab78","name":"","links":["4e636188.7f332"],"x":235,"y":2400,"wires":[["b8dd13b1.797cb"]]},{"id":"ba0630734df9353f","type":"hubitat command","z":"f9337f21.0eab78","deviceLabel":"Porch Bulb","name":"","server":"252d4ef4.c14b6a","deviceId":"66","command":"","commandArgs":"","x":690,"y":2360,"wires":[[]]},{"id":"2c07bcd4127d212c","type":"inject","z":"f9337f21.0eab78","name":"Every 15 minutes","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"string"}],"repeat":"900","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":170,"y":2240,"wires":[["ed59489e0b1aba05"]]},{"id":"89753df20ca7d578","type":"delay","z":"f9337f21.0eab78","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":575,"y":2360,"wires":[["ba0630734df9353f"]],"l":false},{"id":"ee0bd27a6442d9c0","type":"change","z":"f9337f21.0eab78","name":"is_red := false","rules":[{"t":"set","p":"is_red","pt":"flow","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":2220,"wires":[["42ed4e7930637962"]]},{"id":"c63d476daa70e7fc","type":"switch","z":"f9337f21.0eab78","name":"is_red?","property":"is_red","propertyType":"flow","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":620,"y":2240,"wires":[["ee0bd27a6442d9c0"],["1657120c75a44639"]]},{"id":"1657120c75a44639","type":"change","z":"f9337f21.0eab78","name":"is_red := true","rules":[{"t":"set","p":"is_red","pt":"flow","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":2260,"wires":[["4505442f74bfd3ab"]]},{"id":"42ed4e7930637962","type":"change","z":"f9337f21.0eab78","name":"Make Green","rules":[{"t":"set","p":"arguments","pt":"msg","to":"{\"hue\": 31, \"saturation\": 55, \"level\": 100}","tot":"json"},{"t":"set","p":"arguments","pt":"msg","to":"$string(msg.arguments)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":990,"y":2220,"wires":[["338150d80eb38946"]]},{"id":"4505442f74bfd3ab","type":"change","z":"f9337f21.0eab78","name":"Make Red","rules":[{"t":"set","p":"arguments","pt":"msg","to":"{\"hue\": 1, \"saturation\": 64, \"level\": 100}","tot":"json"},{"t":"set","p":"arguments","pt":"msg","to":"$string(msg.arguments)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":990,"y":2260,"wires":[["338150d80eb38946"]]},{"id":"338150d80eb38946","type":"delay","z":"f9337f21.0eab78","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1115,"y":2240,"wires":[["4abace46d88d5d82"]],"l":false},{"id":"4abace46d88d5d82","type":"hubitat command","z":"f9337f21.0eab78","deviceLabel":"Porch Bulb","name":"","server":"252d4ef4.c14b6a","deviceId":"66","command":"setColor","commandArgs":"","x":1230,"y":2240,"wires":[[]]},{"id":"7bbc68f86666af49","type":"inject","z":"f9337f21.0eab78","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":895,"y":2160,"wires":[["42ed4e7930637962"]],"l":false},{"id":"23abbe03a5af6625","type":"inject","z":"f9337f21.0eab78","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":895,"y":2320,"wires":[["4505442f74bfd3ab"]],"l":false},{"id":"ed59489e0b1aba05","type":"within-time-switch","z":"f9337f21.0eab78","name":"","positionConfig":"96c207ac.2237a8","startTime":"sunsetEnd","startTimeType":"pdsTime","startOffset":0,"startOffsetType":"none","startOffsetMultiplier":60000,"endTime":"23:00","endTimeType":"entered","endOffset":0,"endOffsetType":"none","endOffsetMultiplier":60000,"timeRestrictions":"","timeRestrictionsType":"none","timeDays":"*","timeOnlyOddDays":false,"timeOnlyEvenDays":false,"timeOnlyOddWeeks":false,"timeOnlyEvenWeeks":false,"timeMonths":"*","timedatestart":"","timedateend":"","propertyStart":"","propertyStartType":"none","propertyStartCompare":"true","propertyStartThreshold":"","propertyStartThresholdType":"num","startTimeAlt":"","startTimeAltType":"entered","startOffsetAlt":0,"startOffsetAltType":"none","startOffsetAltMultiplier":60000,"propertyEnd":"","propertyEndType":"none","propertyEndCompare":"true","propertyEndThreshold":"","propertyEndThresholdType":"num","endTimeAlt":"","endTimeAltType":"entered","endOffsetAlt":0,"endOffsetAltType":"none","endOffsetAltMultiplier":60000,"withinTimeValue":"","withinTimeValueType":"msgInput","outOfTimeValue":"","outOfTimeValueType":"msgInput","tsCompare":"0","x":390,"y":2240,"wires":[["c63d476daa70e7fc"],[]]},{"id":"96c207ac.2237a8","type":"position-config","name":"Home","isValide":"true","longitude":"0","latitude":"0","angleType":"deg","timeZoneOffset":"99","timeZoneDST":"0","stateTimeFormat":"3","stateDateFormat":"12"},{"id":"252d4ef4.c14b6a","type":"hubitat config","name":"Hubitat","usetls":false,"host":"172.16.0.5","port":"80","appId":"14","nodeRedServer":"http://172.16.0.25:1880","webhookPath":"/hubitat/webhook","autoRefresh":false,"useWebsocket":false,"colorEnabled":false,"color":"#000000"}]
4 Likes

Thanks for the ideas!!!

I'd like to offer my simple subflow that can handle a sequence of commands... You can either pass one message to the subflow with RUN_ALL set to "true" and it will automatically progress through the list of commands returning a joined result array message OR multiple times with RUN_ALL set to "false" which allows a step by step approach, with each new message progressing though the list and rolling over to the first command.

This is just the subflow with a bogus HE Config..

Simple Command Sequencer - heSequence (updated)

[{"id":"bd405dcfd9263255","type":"subflow","name":"heSequence","category":"","in":[{"x":50,"y":30,"wires":[{"id":"6ec468a9c0b0abf9"}]}],"out":[{"x":1140,"y":60,"wires":[{"id":"faa1f62b019404a1","port":1},{"id":"3b80fac98ba1259c","port":0}]}],"env":[{"name":"TOPIC","type":"str","value":"heSequence"},{"name":"COMMANDS","type":"json","value":"[{\"name\":\"green\",\"deviceId\":\"1773\",\"command\":\"setColor\",\"arguments\":{\"hue\":36,\"saturation\":100,\"level\":50},\"delaySecs\":5},{\"name\":\"red\",\"deviceId\":\"1773\",\"command\":\"setColor\",\"arguments\":{\"hex\":\"FF0000\"},\"delaySecs\":5}]"},{"name":"RUN_ALL","type":"bool","value":"true"}],"meta":{},"color":"#DDAA99","status":{"x":1140,"y":280,"wires":[{"id":"a840e3a34d7b74c5","port":0}]}},{"id":"be25f6810307808d","type":"function","z":"bd405dcfd9263255","name":"set device command","func":"//commands = msg.payload;\ntopic = env.get(\"TOPIC\");\ncommands = env.get(\"COMMANDS\");\n//node.warn(commands);\n\nvar len = commands.length;\n\nvar current = flow.get(\"current\");\nif (current === undefined ){\n    current = 0;\n}\nif( current < (len-1)) {\n    current++;\n} else {\n    current = 0;\n}\nflow.set(\"current\",current);\n\nvar command = commands[current];\n\nvar retMsg = {\n    \"topic\": env.get(\"TOPIC\")\n    ,\"name\": command.name\n    ,\"command\": command.command\n    ,\"delay\": command.delaySecs\n    ,\"deviceId\": command.deviceId\n}\n\nif (command.arguments!==\"\") {\n    var val = typeof command.arguments == \"object\" ? JSON.stringify(command.arguments) : command.arguments;\n    retMsg.arguments = val;\n}\n\nflow.set(\"statusMsg\", retMsg);\n\nreturn retMsg;\n\n/*\nvar keys = Object.keys(command);\nconst ignore = new Set([\"delaySecs\",\"name\",\"deviceId\"]);\n\nfor (var i=0;i<keys.length;i++){\n    var key = keys[i];\n    if( !ignore.has(key) ){\n\n        if (command[key]===\"\") {\n            retMsg = {\n              \"topic\": topic\n              ,\"command\": key\n              , \"payload\": \"\"\n              ,\"deviceId\": command.deviceId\n              ,\"delay\": delay\n            } \n        } else {\n            var val = typeof command[key] == \"object\" ? JSON.stringify(command[key]) : command[key];\n            \n            retMsg = {\n              \"topic\": topic\n              ,\"command\": key\n              ,\"arguments\": val\n              , \"payload\": \"\"\n              ,\"deviceId\": command.deviceId\n              ,\"delay\": delay\n            } \n            \n        }\n        \n        flow.set(\"statusMsg\", retMsg);\n        node.send(retMsg);\n        node.done();\n    }\n}\n\nreturn retMsg;\n*/\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":140,"wires":[["eb6265f63788fd28"]]},{"id":"a840e3a34d7b74c5","type":"change","z":"bd405dcfd9263255","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"\t($flowContext(\"current\") + 1) & \" of \" & $count($env(\"COMMANDS\")) & \" - \" & $flowContext(\"statusMsg\").name\t& \" / \" & payload\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":920,"y":320,"wires":[[]]},{"id":"88ee93fe62787abb","type":"stoptimer-varidelay","z":"bd405dcfd9263255","duration":"5","durationType":"num","units":"Second","payloadtype":"num","payloadval":"0","name":"","reporting":"every_second","persist":false,"ignoretimerpass":false,"x":700,"y":220,"wires":[["faa1f62b019404a1"],[],["a840e3a34d7b74c5"]]},{"id":"faa1f62b019404a1","type":"switch","z":"bd405dcfd9263255","name":"$RUN_ALL?","property":"$env(\"RUN_ALL\")","propertyType":"jsonata","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":930,"y":140,"wires":[["99f2e3e687f1528d"],[]]},{"id":"99f2e3e687f1528d","type":"switch","z":"bd405dcfd9263255","name":"Not Done?","property":"( $count($env(\"COMMANDS\")) != ($flowContext(\"current\") + 1))\t","propertyType":"jsonata","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":350,"y":60,"wires":[["be25f6810307808d","0fd3311ee7ba1738"],["0fd3311ee7ba1738"]]},{"id":"0fd3311ee7ba1738","type":"join","z":"bd405dcfd9263255","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":670,"y":60,"wires":[["3b80fac98ba1259c"]]},{"id":"eb6265f63788fd28","type":"hubitat command","z":"bd405dcfd9263255","deviceLabel":"","name":"","server":"623daead.b1d2b","deviceId":"","command":"","commandArgs":"","x":680,"y":140,"wires":[["78776570158e1106"]]},{"id":"78776570158e1106","type":"function","z":"bd405dcfd9263255","name":"set delay = flow.statusMsg.delay","func":"\nvar statusMsg = flow.get(\"statusMsg\");\nmsg.delay = statusMsg.delay;\n\nvar runAll = env.get(\"RUN_ALL\");\nvar current = flow.get(\"current\");\nvar key = current.toString() + \" - \" + statusMsg.name;\n\nif(runAll) {\n    \n    msg.payload = {\n        \"name\": statusMsg.name\n        ,\"deviceId\": msg.deviceId\n        ,\"command\": msg.command\n        ,\"arguments\": msg.arguments\n        ,\"response\": msg.response\n        ,\"requestCommand\": msg.requestCommand\n        ,\"requestArguments\": msg.requestArguments\n    }\n    \n    msg.parts = {\n        \"id\": env.get(\"TOPIC\"),\n        \"index\": current,\n        \"count\": env.get(\"COMMANDS\").length,\n        \"type\":\"object\",\n        \"ch\":\"\",\n        \"key\": key,\n        \"len\":\"\"\n    }\n}\n\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":220,"wires":[["88ee93fe62787abb"]]},{"id":"3b80fac98ba1259c","type":"change","z":"bd405dcfd9263255","name":"cleanup msg","rules":[{"t":"delete","p":"command","pt":"msg"},{"t":"delete","p":"deviceId","pt":"msg"},{"t":"delete","p":"arguments","pt":"msg"},{"t":"delete","p":"response","pt":"msg"},{"t":"delete","p":"requestCommand","pt":"msg"},{"t":"delete","p":"requestArguments","pt":"msg"},{"t":"delete","p":"delay","pt":"msg"},{"t":"delete","p":"_timerpass","pt":"msg"},{"t":"delete","p":"name","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":930,"y":60,"wires":[[]]},{"id":"6ec468a9c0b0abf9","type":"switch","z":"bd405dcfd9263255","name":"payload != stop","property":"payload != \"stop\"","propertyType":"jsonata","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":120,"y":320,"wires":[["be25f6810307808d"],["014b9b4e013257f2"]]},{"id":"014b9b4e013257f2","type":"change","z":"bd405dcfd9263255","name":"","rules":[{"t":"set","p":"current","pt":"flow","to":"-1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":320,"wires":[["88ee93fe62787abb"]]},{"id":"623daead.b1d2b","type":"hubitat config","name":"YourHEHub","usetls":false,"host":"[your HE ip]","port":"80","appId":"[your appId]","nodeRedServer":"http://[your nr ip]:1880","webhookPath":"/hubitat/webhook_","autoRefresh":true,"useWebsocket":false,"colorEnabled":false,"color":"#000000"}]

Warning: still futzing around and there may be a bug or two left. Also notice that in the arguments field it handles the conversion to a JSON string.. When doing a "RUN_ALL" a joined array of command results is returned...

Further Notes:
Forgot to mention - this requires the node-red-contrib-stoptimer-varidelay node - I am using that instead of the "delay" node. Also to stop the the process midway send a msg.payload = "stop".

1 Like

Hoping for some help and direction with a flow and this seems like a good place to ask. I've gone to NodeRED for "Alexa aware" responses, i.e. responses from the Alexa you're speaking to and commands sent to appropriate devices in the same room. What I'd like to do in this situation is ask Alexa "which door is open" and have her respond with a canned answer (the back door is open), based on contact sensor status in hubitat. What's the best/easiest way to have NR check hubitat sensor status and route to the appropriate Alexa Speak Routine. I can handle the speaking part but I haven't used device nodes to route based on status yet. Thanks in advance.

That should be fairly easy to accomplish...

You'd need one of the Alexa nodes.. I use this one:

Then you would need to attach to your Amazon account and give permission in order to set up the configuration. Note: it will make you browse to a specific site on the NR server in order to do the Amazon login.. you might have to do some creative tunneling.

Once done, in Alexa you create a routine with the phrase like "which doors are open?" and have it do a "wait" action for like 5 seconds - nothing else is needed.

On the Node-RED side it's just a matter of looking for a particular phrase using the Alexa Event Node and "msg.payload.description.summary" and then testing the sensors to see which one(s) are active and speak the result using the Alexa Routine node.

1 Like

Thanks for the response! I can do everything down to the testing the sensor part already. I can have Alexa speak whatever phrase from whichever device I choose, including the one I speak too. I'm foggy on how to test the hubitat device nodes and route the appropriate response. I don't quite know how to create the if/then logic in NodeRED.

There are a couple of ways to do this including using joins etc.. Here is a very simple example using my office lights.. what this sequence does accumulate the status of each "on" light in a msg property called "status". "msg.topic" contains the name of the device.

The change node and switch node use JSONATA.. I put the expressions in the name so you can see them. You can add as many devices as you want..

payload.value = "on" ?
(status != "" ? status & " and " : "") & topic
: status

Note: both change nodes are the same - I did this so all you would have to do is copy/paste for each device you want to use..

EDIT Now that I've re-read your post, I see that I'm not picking up the output after the switch node like you are, where it seems you're checking for the existence of msg.status. I'm not sure what's going on in that switch statement so that's probably what I'm missing.

2nd EDIT I'm learning! :smile: It occurred to me that maybe I didn't understand exactly the output I was seeing in the debug log. With more than one door open, injecting a timestamp to give me the value of msg.status NOW, does indeed show me the accumulating string. So it was there, I just didn't know how to see it properly I'm assuming. I'm still tinkering with setting msg.status when no doors are open.

Thanks so much for the time and effort. I have no experience with jsonata, until now, so I've been reading up and I believe I understand the syntax and what the expression is doing each time a device changes. For some reason msg.status is not accumulating, just listing the current device that's open. I haven't been able to figure out what I've done wrong. Screenshots below. Secondly, when no door is open, msg.status is undefined. In your example, you seem to have msg.status set to "No lights are on" if all lights are off. How do you set that string as "default"? (all doors are closed in my case).


test2
test3
test4

Success! This has been a great exercise for me. Thanks @erktrek for lighting the way. Here's the current flow that's working. I realized that you have to "restart the flow" to get the accumulated msg.status so I tied in the alexa listens event to refresh it everytime she's asked. I used a big switch statement to cobble together all the possible values of msg.status and then set a "cleaned up" response so she sounds more natural. There's probably a much better way to do that part, or you could just deal with the robotic speech and pass the variable untouched. If there's any hints or tips you have or anything you feel like I don't understand, please feel free. Thanks.

P.S DON'T use an ampersand in a string you're passing to alexa to speak. She doesn't like that and will go off about a Simon Says skill that she can't reach right now. Seriously don't do that. :slight_smile:

2 Likes

Would you mind post your flow, I what to do this exact same thing.

TIA

Mike

1 Like

Title - Ask Alexa which door is open (any device in any state)

Summary - This flow allows me to ask Alexa "Which door is open" and have her respond from the device I asked which door(s) if any, are open. This can be adapted to be any device in any state. I have inovelli red series dimmers and I use the LED notification bars for a number of things. Sometimes it isn't immediately obvious WHICH specific device is responsible for the notification. Occasionally, the LED bars don't update even though all devices are in the desired state, so I've added a virtual switch which clears the LED bar notifications, and if Alexa determines that all devices are as they should be, she clears the notification. Modules required are node-red-contrib-alexa-remote2-applestrudel and node-red-contrib-hubitat. Credit to @erktrek for the considerable assistance getting it running.

Picture -

Flow -

[{"id":"952642caef2d6e90","type":"tab","label":"Alexa, Which Door","disabled":false,"info":""},{"id":"8cb9b3df384674c9","type":"hubitat device","z":"952642caef2d6e90","deviceLabel":"Front Door Sensor","name":"Front Door","server":"e2175bd0.e82808","deviceId":"426","attribute":"contact","sendEvent":true,"x":230,"y":160,"wires":[["4ad8bb4b08215cc7"]]},{"id":"541561a97bb0c876","type":"hubitat device","z":"952642caef2d6e90","deviceLabel":"Back Door Sensor","name":"Back Door","server":"e2175bd0.e82808","deviceId":"425","attribute":"contact","sendEvent":true,"x":230,"y":260,"wires":[["8d51dd9d8fd6822e"]]},{"id":"38d018e25e193a15","type":"hubitat device","z":"952642caef2d6e90","deviceLabel":"Basement Patio Door Sensor","name":"Patio Door","server":"e2175bd0.e82808","deviceId":"427","attribute":"contact","sendEvent":true,"x":230,"y":360,"wires":[["09085daac7cdb883"]]},{"id":"4ad8bb4b08215cc7","type":"change","z":"952642caef2d6e90","name":"payload.value = \"open\" ?\\n \t(status != \"\" ? status & \" and \" : \"\") & topic\\n \t: status","rules":[{"t":"set","p":"status","pt":"msg","to":"payload.value = \"open\" ? \t(status != \"\" ? status & \" and \" : \"\") & topic \t: status","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":160,"wires":[["541561a97bb0c876"]]},{"id":"8d51dd9d8fd6822e","type":"change","z":"952642caef2d6e90","name":"payload.value = \"open\" ?\\n \t(status != \"\" ? status & \" and \" : \"\") & topic\\n \t: status","rules":[{"t":"set","p":"status","pt":"msg","to":"payload.value = \"open\" ? \t(status != \"\" ? status & \" and \" : \"\") & topic \t: status","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":260,"wires":[["38d018e25e193a15"]]},{"id":"09085daac7cdb883","type":"change","z":"952642caef2d6e90","name":"payload.value = \"open\" ?\\n \t(status != \"\" ? status & \" and \" : \"\") & topic\\n \t: status","rules":[{"t":"set","p":"status","pt":"msg","to":"payload.value = \"open\" ? \t(status != \"\" ? status & \" and \" : \"\") & topic \t: status","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":360,"wires":[["3c4e8d7e167fc4e7"]]},{"id":"3c4e8d7e167fc4e7","type":"switch","z":"952642caef2d6e90","name":"","property":"status","propertyType":"msg","rules":[{"t":"null"},{"t":"eq","v":"Front Door","vt":"str"},{"t":"eq","v":"Back Door","vt":"str"},{"t":"eq","v":"Patio Door","vt":"str"},{"t":"eq","v":"Front Door and Back Door","vt":"str"},{"t":"eq","v":"Back Door and Patio Door","vt":"str"},{"t":"eq","v":"Front Door and Patio Door","vt":"str"},{"t":"eq","v":"Front Door and Back Door and Patio Door","vt":"str"}],"checkall":"true","repair":false,"outputs":8,"x":830,"y":240,"wires":[["8aeda17b28698363"],["1d748c93a73f94b6"],["9e0fd186d72017dd"],["3c3425218d089803"],["0f443b74ab442cc8"],["48f4e9d11132e645"],["d252d69452406cd4"],["31479842620f44d9"]]},{"id":"8aeda17b28698363","type":"change","z":"952642caef2d6e90","name":"All Doors are Closed","rules":[{"t":"set","p":"textToSpeak","pt":"flow","to":"Hubitat reports all doors are closed","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1060,"y":120,"wires":[["1a6490052101ced6"]]},{"id":"08c88da7ed128ccd","type":"alexa-remote-event","z":"952642caef2d6e90","name":"","account":"55e8b5ec0dcbeaf2","event":"ws-device-activity","x":110,"y":60,"wires":[["90f5e787a1e3c4f2","8cb9b3df384674c9"]]},{"id":"90f5e787a1e3c4f2","type":"switch","z":"952642caef2d6e90","name":"Which Door is Open","property":"payload.description.summary","propertyType":"msg","rules":[{"t":"cont","v":"which door is open","vt":"str"},{"t":"cont","v":"is there a door open","vt":"str"},{"t":"cont","v":"what door is open","vt":"str"},{"t":"cont","v":"are all the doors closed","vt":"str"},{"t":"cont","v":"are there any doors open","vt":"str"},{"t":"cont","v":"which doors are open","vt":"str"},{"t":"cont","v":"which doors open","vt":"str"}],"checkall":"false","repair":false,"outputs":7,"x":420,"y":60,"wires":[["e02462808a329271"],["e02462808a329271"],["e02462808a329271"],["e02462808a329271"],["e02462808a329271"],["e02462808a329271"],["e02462808a329271"]]},{"id":"ce026cb65621cfa0","type":"alexa-remote-routine","z":"952642caef2d6e90","name":"","account":"55e8b5ec0dcbeaf2","routineNode":{"type":"speak","payload":{"type":"regular","text":{"type":"flow","value":"textToSpeak"},"devices":{"type":"flow","value":"device"}}},"x":880,"y":60,"wires":[[]]},{"id":"e02462808a329271","type":"change","z":"952642caef2d6e90","name":"","rules":[{"t":"set","p":"device","pt":"flow","to":"payload.deviceSerialNumber","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":60,"wires":[["ce026cb65621cfa0"]]},{"id":"1d748c93a73f94b6","type":"change","z":"952642caef2d6e90","name":"The Front Door is Open","rules":[{"t":"set","p":"textToSpeak","pt":"flow","to":"The Front Door Is Open","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1070,"y":160,"wires":[[]]},{"id":"9e0fd186d72017dd","type":"change","z":"952642caef2d6e90","name":"The Back Door is Open","rules":[{"t":"set","p":"textToSpeak","pt":"flow","to":"The Back Door Is Open","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1070,"y":200,"wires":[[]]},{"id":"3c3425218d089803","type":"change","z":"952642caef2d6e90","name":"The Patio Door is Open","rules":[{"t":"set","p":"textToSpeak","pt":"flow","to":"The Patio Door Is Open","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1070,"y":240,"wires":[[]]},{"id":"0f443b74ab442cc8","type":"change","z":"952642caef2d6e90","name":"The Front Door and Back Door are both Open","rules":[{"t":"set","p":"textToSpeak","pt":"flow","to":"The Front Door and Back Door are both Open","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1140,"y":280,"wires":[[]]},{"id":"48f4e9d11132e645","type":"change","z":"952642caef2d6e90","name":"The Back Door and Patio Door are both Open","rules":[{"t":"set","p":"textToSpeak","pt":"flow","to":"The Back Door and Patio Door are both Open","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1140,"y":320,"wires":[[]]},{"id":"31479842620f44d9","type":"change","z":"952642caef2d6e90","name":"All doors are open. I've checked twice.","rules":[{"t":"set","p":"textToSpeak","pt":"flow","to":"All doors are open. I've checked twice.","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1110,"y":400,"wires":[[]]},{"id":"d252d69452406cd4","type":"change","z":"952642caef2d6e90","name":"The Front Door and Patio Door are both Open","rules":[{"t":"set","p":"textToSpeak","pt":"flow","to":"The Front Door and Patio Door are both Open","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1140,"y":360,"wires":[[]]},{"id":"1a6490052101ced6","type":"hubitat command","z":"952642caef2d6e90","deviceLabel":"vsClearSwitchNotifications","name":"","server":"e2175bd0.e82808","deviceId":"674","command":"on","commandArgs":"","x":1340,"y":120,"wires":[[]]},{"id":"e2175bd0.e82808","type":"hubitat config","name":"HUBITAT HUB","usetls":false,"host":"192.168.19.8","port":"80","appId":"48","nodeRedServer":"http://192.168.19.7:1880","webhookPath":"/hubitat/webhook","autoRefresh":false,"useWebsocket":false,"colorEnabled":false,"color":"#000000"},{"id":"55e8b5ec0dcbeaf2","type":"alexa-remote-account","name":"","authMethod":"proxy","proxyOwnIp":"192.168.19.7","proxyPort":"3456","cookieFile":"authFile","refreshInterval":"3","alexaServiceHost":"pitangui.amazon.com","amazonPage":"amazon.com","acceptLanguage":"en-US","onKeywordInLanguage":"on","userAgent":"","useWsMqtt":"on","autoInit":"on"}]
3 Likes

Thanks, I'm still learning NR so this will help

Help!

I trying to duplicate this rule form HE in NR. I've tried a combination of switch, change, Boolean, etc. and just can't seem to get it to work.

image

Here's essentially what I'm trying to achieve.

[{"id":"0258e697074ba84e","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"799a401b17e58b93","type":"hubitat device","z":"0258e697074ba84e","deviceLabel":"vSwitch","name":"","server":"de459b47a8a34d86","deviceId":"2807","attribute":"switch","sendEvent":true,"x":113,"y":81,"wires":[["4e2de370f6cbe274"]]},{"id":"4e2de370f6cbe274","type":"change","z":"0258e697074ba84e","name":"Switch to Bool","rules":[{"t":"change","p":"payload.value","pt":"msg","from":"on","fromt":"str","to":"true","tot":"str"},{"t":"change","p":"payload.value","pt":"msg","from":"off","fromt":"str","to":"false","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":313,"y":81,"wires":[["a8a65d29b0d59e85"]]},{"id":"a8a65d29b0d59e85","type":"BooleanLogicUltimate","z":"0258e697074ba84e","name":"","filtertrue":"both","persist":true,"sInitializeWith":"WaitForPayload","triggertopic":"trigger","outputtriggeredby":"all","inputCount":"3","topic":"result","restrictinputevaluation":true,"x":553,"y":121,"wires":[[],[],[]]},{"id":"d7fd5153089b0239","type":"change","z":"0258e697074ba84e","name":"Door to Bool","rules":[{"t":"change","p":"payload","pt":"msg","from":"closed","fromt":"str","to":"false","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"open","fromt":"str","to":"true","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":293,"y":141,"wires":[["a8a65d29b0d59e85"]]},{"id":"c38947ebd78f9b03","type":"change","z":"0258e697074ba84e","name":"Door to Bool","rules":[{"t":"change","p":"payload.value","pt":"msg","from":"closed","fromt":"str","to":"false","tot":"str"},{"t":"change","p":"payload.value","pt":"msg","from":"open","fromt":"str","to":"true","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":293,"y":201,"wires":[["a8a65d29b0d59e85"]]},{"id":"d4c35c5c19ea7218","type":"hubitat device","z":"0258e697074ba84e","deviceLabel":"vDoor 1","name":"","server":"de459b47a8a34d86","deviceId":"3001","attribute":"contact","sendEvent":true,"x":113,"y":141,"wires":[["d7fd5153089b0239"]]},{"id":"6b3595f5b4edbad8","type":"hubitat device","z":"0258e697074ba84e","deviceLabel":"vDoor 2","name":"","server":"de459b47a8a34d86","deviceId":"3002","attribute":"contact","sendEvent":true,"x":113,"y":201,"wires":[["c38947ebd78f9b03"]]},{"id":"de459b47a8a34d86","type":"hubitat config","name":"TheNutHouse Hubitat","usetls":false,"host":"0.0.0.0","port":"80","appId":"2798","nodeRedServer":"http://0.0.0.0:1880","webhookPath":"/hubitat/webhook","autoRefresh":true,"useWebsocket":false,"colorEnabled":false,"color":"#ace043"}]

just string them together in a row. No need for a logic node in a situation like that.

Ok now I understand what I was seeing when I saw flows constructed like this.

However its not quite what I need.

The HE original rule is triggered by either motion sensors or contact sensors and any of the doors being open or switch on prevents the action from running.

The example you posted is cumulative and only works if all three conditions are closed/off.

I need any open or on. That's why I was pursuing the logic route.

Thanks for the first ah-ha.

Sorry realized there was a bigger issue so had to delete my prior post.. I think this is what you want:

The main issue you have is the Boolean Node expects "msg.payload" to be true or false NOT "msg.payload.value" - you are currently passing "msg.payload" as a JSON object NOT a boolean value. The above uses JSONATA to return a true/false based on whether the payload.value = "on" or not. You will need to modify the other change nodes to do something similar and test for "open" instead of "on".

edit: for extra efficiency and fun (and who doesn't want that?? :wink:) simply modifying the JSONATA change node expression to use an "OR" means you can run everything through a single change node like this:

2 Likes

Maybe a full explanation of what I want to accomplish. Here's the full rule.

There are motion sensors in the garage/shed and contact sensor on man door and garage doors. Plus I have another shed with a contact sensor on the door and an interior motion sensor.

I use a 24/7 rule to alert me (notify, alexa speaks & pushover) if any motion or door open/close. But the alert only occurs if the house doors are closed and a virtual switch is off. If I'm working outside one or both of the doors are open or I turn on the virtual switch.

Based on your rule, I do not see the need to use a Boolean logic node. You need three switch nodes in a row to test whether:

  1. Basement Door is closed
  2. Back Door is closed
  3. Work Outside is off

The device nodes that preface these switch nodes should not have "Send Events" checked.

The sequence would be triggered by any of the device nodes you have listed (Back Shed Door, Garage Door Left, etc) going through a single switch node which tests for the value of msg.payload.value being either open or active. Note that these device nodes should have "Send Events" checked.

2 Likes

The other thing to do to make things easier is to use the "Zone Motion Controllers" app in HE and create a virtual motion device of all your motion sensors which you can expose to Node-RED. That way it's only one device to test.

1 Like

Like this?

[{"id":"0258e697074ba84e","type":"tab","label":"Intrusion Test","disabled":false,"info":"","env":[]},{"id":"799a401b17e58b93","type":"hubitat device","z":"0258e697074ba84e","deviceLabel":"vSwitch","name":"","server":"de459b47a8a34d86","deviceId":"2807","attribute":"switch","sendEvent":false,"x":460,"y":220,"wires":[["63db66ed99e5ab7a"]]},{"id":"d4c35c5c19ea7218","type":"hubitat device","z":"0258e697074ba84e","deviceLabel":"vDoor 1","name":"","server":"de459b47a8a34d86","deviceId":"3001","attribute":"contact","sendEvent":false,"x":460,"y":60,"wires":[["c23cd0c5c4d6eb91"]]},{"id":"6b3595f5b4edbad8","type":"hubitat device","z":"0258e697074ba84e","deviceLabel":"vDoor 2","name":"","server":"de459b47a8a34d86","deviceId":"3002","attribute":"contact","sendEvent":false,"x":460,"y":140,"wires":[["38a7d0e6798ba0cb"]]},{"id":"63db66ed99e5ab7a","type":"switch","z":"0258e697074ba84e","name":"on/off","property":"payload.value","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":617,"y":219,"wires":[[],["85a0974606184f94"]]},{"id":"c23cd0c5c4d6eb91","type":"switch","z":"0258e697074ba84e","name":"open/closed","property":"payload.value","propertyType":"msg","rules":[{"t":"eq","v":"open","vt":"str"},{"t":"eq","v":"closed","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":637,"y":59,"wires":[[],["6b3595f5b4edbad8"]]},{"id":"38a7d0e6798ba0cb","type":"switch","z":"0258e697074ba84e","name":"open/closed","property":"payload.value","propertyType":"msg","rules":[{"t":"eq","v":"open","vt":"str"},{"t":"eq","v":"closed","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":637,"y":139,"wires":[[],["799a401b17e58b93"]]},{"id":"85a0974606184f94","type":"debug","z":"0258e697074ba84e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":900,"y":220,"wires":[]},{"id":"dc090561bb819dcf","type":"inject","z":"0258e697074ba84e","name":"Motion garage active","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"name\":\"motion\",\"value\":\"active\",\"displayName\":\"Motion Garage\",\"deviceId\":\"855\",\"descriptionText\":\"Motion Garage is active\",\"unit\":null,\"type\":null,\"data\":null,\"currentValue\":\"active\",\"dataType\":\"ENUM\",\"values\":[\"inactive\",\"active\"]}","payloadType":"json","x":270,"y":60,"wires":[["d4c35c5c19ea7218"]]},{"id":"de459b47a8a34d86","type":"hubitat config","name":"TheNutHouse Hubitat","usetls":false,"host":"192.168.0.199","port":"80","appId":"2798","nodeRedServer":"http://192.168.0.16:1880","webhookPath":"/hubitat/webhook","autoRefresh":true,"useWebsocket":false,"colorEnabled":false,"color":"#ace043"}]
2 Likes

Yup - Exactly!

Just want to mention your switch nodes don't even have to test for the open/on condition.

1 Like