I'm going to try a different approach vs the "samples" Topic.. not just a copy paste of an image and a bucket of code, but an outline of why I chose this path.
First, this uses a Function node and so I'll start by apologizing to all of the people that just went "ewwww"... sorry. I went the other direction, trying to pack it all into one.
I have a "Gloomy Day" Rule that watches MultiSensor 6 illuminance values. If the illuminance is below a threshold, I call it a gloomy day and turn on some extra lights. When the gloom dissipates, I turn the lights back off.
In my situation I've picked 4 of my dozen or so illuminance reporters and plotted them over time. I found values for my rooms, my specific MS6's that work for me. If you want to try this, you'll have to determine the values for your house, your rooms.
Now I need to determine that all the 'zones' are above the predetermined value. When they are, illuminance is considered 'true' and the lights can be turned off. Yes, true equals off.
There's a old technique for comparing a value against a range... (x - min) * (x - max) <= 0 is true if it's within range, false if not.
For me, I just care that it's above a value, therefore min=0 and the entire term can be discarded: (x-max) <= 0
Functions are written in Javascript and javascript 'trickery' allows one to add booleans:
a += (x-max) <= 0
a += (y-max) <= 0
if (a >=2) then.... functions as an AND
Got 4 devices like I do then you just += them all and the compare is a >= 4
You can paste this into your favorite JavaScript tester and see it in action:
var x = 17;
var y = 16;
var z = 55;
var o = 651;
var delta = false;
delta += (x - 18) >=0;
console.warn (delta);
delta += (y - 18) >=0;
console.warn (delta);
delta += (z - 40) >=0;
console.warn (delta);
delta += (o - 650) >=0;
console.warn (delta);
I used https://playcode.io/ in my example
The Console output looks like:
0
0
1
2
for a total of 2 trues.. not enough, I need 4 trues. You can change the values in the top 4 lines and watch the results change.
I have my core answer now, I just need to make it usable. Function Nodes allow you to have as many outputs as you want, and I want 2.. equivalent to a Switch Node looking for true vs false.
if (delta >= 4 )
{return [msg, null];}
else
{return [null, msg];}
The msg gets sent to the first output if True, the 2nd output if False, precisely like a Switch Node
That leaves only the input side of things.. I need to get "z y z and o" from my MultiSensors.. and I use a different technique there too..
JavaScript doesn't have a Map method like Groovy, but if you squint, key: value pairs are the same anywhere...
I define a Flow specific variable, initialize it to 'empty' then as each Hubitat Event occurs, I save it. This way I can check all values on each new Event, because I want 4 True's. These 3 lines do this for me.. get the 'map' and update the latest Event, then save it back.
prState = flow.get('prState5');
prState[msg.topic.split(" ").slice(-1)] = msg.payload.value
flow.set('prState5', prState);
My MultiSensors all have names that make sense to me, and in this case I want the 2nd portion of the name. Thus if the name of my MultiSensor is "MultiSensor6K (familyroom)" I use the "(familyroom)" portion as the Key in the Key:value pair.
That's all the bit and pieces... going back to the original equation, instead of "x" I use:
delta += prState['(familyroom)'] - 18 >= 0;
to compare the Illuminance value of the 'familyroom' MultiSensor to 18 (lux) along with 3 others for the total of 4.
Here's the entire Function:
/* generic state memory.
Each event has a topic and payload which are stored as a Key:Value pair.
All the pairs are retrieved, one is updated, then all are saved for next time.
*/
prState = flow.get('prState5');
prState[msg.topic.split(" ").slice(-1)] = msg.payload.value
flow.set('prState5', prState);
//node.warn("t="+msg.topic.split(" ").slice(-1)+":"+msg.payload.value);
// Use the mapped key[value] to perform the logic, boolean or arithmetic.
var delta = false;
delta += prState['(familyroom)'] - 18 >= 0;
delta += prState['(livingroom3)'] - 18 >= 0;
delta += prState['(kitchen)'] - 30 >= 0;
delta += prState['(frontWalkway)'] - 650 >= 0;
if (delta >= 4 )
{return [msg, null];}
else
{return [null, msg];}
I hope this is of some value.. perhaps you're having trouble sleeping...
Just to be clear.. this is about 20 seconds worth of clicking in RuleMachine. It's 8x harder in Node-Red. But the FUN is in converting... naturally