Check multiple conditions

Hi
been using node red a little while but by no means an expert. Now that i have set my capability level, here is the problem i am trying to solve.

I wish to run a flow that checks multiple conditions of door and window sensors and route one way if all secure, and another way if it spots something not secure.

Have all my entity states writing to global variables to make things a bit easier (windows show as off and on and i wanted open and shut) so the variables all now show locked or unlocked for doors and open or shut for windows.

Suspected i needed a function node to check multiple IF AND statements followed by ELSEIF statement but cant figure out the syntax.

Does anyone have an example syntax to share to check multiple variables == something do this, else do something else?

thanks for your help as always.
Darren

Hi.

Node-Red doesn't quite work as you explain in the post. That isn't a bad thing, but just to explain to you this thing.

To check multiple conditions of door and window sensors.

No problem. You will need multiple Inputs though. Unless you use a messaging protocol which is a whole other layer of stuff.

For now I'll keep it simple and use discreet inputs to the GPIO pins of the RasPi.
Note: This can be dangerous

You set up a switch that is either open or closed depending on the state of the door/window.

Let's say they are open is the door/window is open and closed if they are closed.
(This helps with keeping terms all the same)

You use a GPIO node and assign it a GPIO pin number - and set it as an INPUT.

I haven't used those pins so I can't explain the details on what you set in the node.

But when the node detects a change on the GPIO pin; it generates a message sent to the flow. (Node-Red code)

That message can be anything you want. But for the sake of keeping it simple I'll say it sends a 1.

You send (connect) that node to another node that detects that 1 and does something.

Depending no how you want things to happen: that can either be to show something on a web page or maybe activate a different GPIO pin (output) to sound an alarm.

No. Things don't happen like that.

This is my take on how things work:

Node-red is not real time like programs written in C or Basic.
Things only happen when things change. Event driven is a good way to put it.

So the node/s looking at the GPIO pins are sitting there. Nothing happening: they don't send/do anything.

When the input changes: They send a message.

That then sets things in motion.
I would maybe suggest you make a test flow to do what you want to happen.

That could be easily don't by replacing the GPIO node with an INJECT node.
You won't need two INJECT nodes. Only one.

That will send/generate a message to simulate something happening.

Unless you want constant / real time monitoring where you see if things are opened and closed dynamically, you don't need to worry too much.
Doing that will introduce a whole other level of complexity to what you are wanting to do and may not really be needed.

Hi Darren

My first question is how is the status of the door/window delivered to NR and how often?

Next, from your write up it is unclear if you are checking ALL the doors and windows at the same time, or if you want to check a single door or window at a time, or if there is a time interval wher you want to check the status of them all.

Changing the state of a window is easy and you can do it with a switch and two change nodes or a function node. If you never want to check for other cases, the function node could be three lines:

if (msg.payload == 'on') msg.payload = 'Open'
else msg.payload = 'Closed';
return msg;

However, why not just use 1 (open/unlocked) and 0(closed/locked) as a status for both doors and windows and then pick what to show when you display the results.

If you want to check all the doors and windows storing them in an array with the 1/0, you could just sum up the value of the status (the 1 or 0's) and if the result is 0 everything is closed/locked otherwise something is open or unlocked.

Thanks @Trying_to_learn

Not sure if I have confused matters, I don’t use RasPi and not sure what GPIO pins are.

Just looking to adjust flow based on multiple condition checks

Thanks

Thanks @zenofmud

Ok the states are checked upon an Alexa routine invoking a Boolean switch at bedtime that runs a flow.
I am wanting to check multiple Sensor states and if all secure to run one leg off a flow and if I detect any insecure states (so am checking multiple sensors) then to run the other leg of the flow.

In the flow I am checking multiple sensors using a function to write a variable for each sensor. So I have multiple variables now with the right status but just need a way of interrogating them in a function JavaScript similar

Does that make sense?
Thanks

Ok, I goofed with not seeing you were using Alexa.

But the messages being received could be analogous to inputs.

But I'll leave things be. Other people are (probably) doing a better job than me.

I don't use Alexa and they seem to, so they know more than me.

This is a case where having a copy of the flow would make it a lot easier to understand.

In order to make code more readable and importable it is important to surround your code with three backticks
```
like this
```

See this post for more details - How to share code or flow json

From what I understand you are just asking for boolean operators syntax in javascript.

I made a small flow to demonstrate some techniques:

  1. Function node with multiple outputs.
  2. Boolean algebra in a function node.
  3. Usage of the join node to combine multiple sensors and check condition on every change.
  4. Usage of global variables to check condition of multiple sensors on an external event.

Hope this demonstrates enough to help you forward.

[{"id":"bffc9ef3.2b7a","type":"inject","z":"df639c3.8eb146","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"open","payloadType":"str","x":170,"y":180,"wires":[["605169b6.92a018"]]},{"id":"53d01ef0.aad7a","type":"inject","z":"df639c3.8eb146","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"close","payloadType":"str","x":170,"y":220,"wires":[["605169b6.92a018"]]},{"id":"3dbfc830.ed4e88","type":"inject","z":"df639c3.8eb146","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":170,"y":320,"wires":[["244ace27.e54e22"]]},{"id":"2ba7326b.7dc14e","type":"inject","z":"df639c3.8eb146","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":170,"y":360,"wires":[["244ace27.e54e22"]]},{"id":"ce8b9f67.3fd43","type":"function","z":"df639c3.8eb146","name":"","func":"let sensors = msg.payload; //don't need to  write msg.payload to acces sensors\n\n//Door open and window not false, or garage 0\nif ( (sensors.door === \"close\" && !sensors.window) || sensors.garage === 0){\n    return [msg, null]; //Send message to first output\n}else if (sensors.garage === 1){\n    return [null, msg]; //Send message to second output\n}\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":780,"y":480,"wires":[["c243dc13.f806"],["e6b83208.c09cd"]]},{"id":"605169b6.92a018","type":"change","z":"df639c3.8eb146","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"door","tot":"str"},{"t":"set","p":"door","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":200,"wires":[["7a26c8cb.a540d8"]]},{"id":"244ace27.e54e22","type":"change","z":"df639c3.8eb146","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"window","tot":"str"},{"t":"set","p":"window","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":340,"wires":[["7a26c8cb.a540d8"]]},{"id":"ed4b4bce.f0f028","type":"inject","z":"df639c3.8eb146","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":170,"y":460,"wires":[["1bb3fe56.54f8a2"]]},{"id":"dc40fb7c.cc6858","type":"inject","z":"df639c3.8eb146","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":170,"y":500,"wires":[["1bb3fe56.54f8a2"]]},{"id":"1bb3fe56.54f8a2","type":"change","z":"df639c3.8eb146","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"garage","tot":"str"},{"t":"set","p":"garage","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":480,"wires":[["7a26c8cb.a540d8"]]},{"id":"7a26c8cb.a540d8","type":"join","z":"df639c3.8eb146","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":630,"y":480,"wires":[["ce8b9f67.3fd43"]]},{"id":"c243dc13.f806","type":"debug","z":"df639c3.8eb146","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":970,"y":440,"wires":[]},{"id":"e6b83208.c09cd","type":"debug","z":"df639c3.8eb146","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":970,"y":520,"wires":[]},{"id":"f7c352e3.10589","type":"inject","z":"df639c3.8eb146","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":600,"y":660,"wires":[["11964d27.27bd13"]]},{"id":"11964d27.27bd13","type":"function","z":"df639c3.8eb146","name":"","func":"let sensors = {\n    door: global.get(\"door\"),\n    garage: global.get(\"garage\"),\n    window: global.get(\"window\")\n}\n\n//Door open and window not false, or garage 0\nif ( (sensors.door === \"close\" && !sensors.window) || sensors.garage === 0){\n    return [msg, null]; //Send message to first output\n}else if (sensors.garage === 1){\n    return [null, msg]; //Send message to second output\n}\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":780,"y":660,"wires":[["c2a4a74.35d5058"],["6fb1b079.c9eb6"]]},{"id":"c2a4a74.35d5058","type":"debug","z":"df639c3.8eb146","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":970,"y":620,"wires":[]},{"id":"6fb1b079.c9eb6","type":"debug","z":"df639c3.8eb146","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":970,"y":700,"wires":[]},{"id":"25d4d137.987afe","type":"comment","z":"df639c3.8eb146","name":"Sensor check on every sensor change","info":"","x":1050,"y":480,"wires":[]},{"id":"cc62648f.e0cd08","type":"comment","z":"df639c3.8eb146","name":"Sensor check on external event","info":"","x":1030,"y":660,"wires":[]}]

thanks @Hopperpop and @zenofmud

I have now included my code below for the bit of flow i am stuck with, the downstream stuff from here is all working fine.

What the flow is doing is getting 4 sensor states, then writing them as global variables as i wish to use them in other flows. I then have two call service nodes that either toggle on or off a boolean helper i have (house secure or not).

This is just part of the larger flow, i have more sensors so just need to check if all in one state or not, in hindsight my variables should probably read secure or not secure rather than open/closed or locked/unlocked as that would make it easier to check if all read secure or not i presume. Hope this helps to explain what i am trying to achieve.

@Hopperpop, imported your flow but struggling a bit to see how i incorporate this, (much more likely to be my understanding than your offer of help!!!)

thanks

[{"id":"15a46d249b8c7845","type":"server-state-changed","z":"58532bd4fd04eec0","name":"End of day routine trigger","server":"2620ec24.eeb984","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.goodnight_sequence","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":170,"y":1200,"wires":[["c6548a0f79a191e5","7819f11e5ed0ded2","87da763460c72a93","96ad7fe03be679a7"],[]]},{"id":"c6548a0f79a191e5","type":"api-current-state","z":"58532bd4fd04eec0","name":"Front door lock state","server":"2620ec24.eeb984","version":2,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"lock.front_door_smart_lock","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":520,"y":1120,"wires":[["1089538f45866cf5"]]},{"id":"7819f11e5ed0ded2","type":"api-current-state","z":"58532bd4fd04eec0","name":"Gym back door left open state","server":"2620ec24.eeb984","version":2,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"binary_sensor.gym_back_left_door_sensor","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":550,"y":1180,"wires":[["9d41272a3989f58e"]]},{"id":"87da763460c72a93","type":"api-current-state","z":"58532bd4fd04eec0","name":"Gym back door right lock state","server":"2620ec24.eeb984","version":2,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"binary_sensor.gym_back_right_door_sensor","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":550,"y":1240,"wires":[["d0fdd5ba9e85d44c"]]},{"id":"96ad7fe03be679a7","type":"api-current-state","z":"58532bd4fd04eec0","name":"Jarvis lock state","server":"2620ec24.eeb984","version":2,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"lock.jarvis_door_lock","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":500,"y":1300,"wires":[["4cddb02641d7ae59"]]},{"id":"d8da9c5af9713c69","type":"inject","z":"58532bd4fd04eec0","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":1120,"wires":[["c6548a0f79a191e5","7819f11e5ed0ded2","87da763460c72a93","96ad7fe03be679a7"]]},{"id":"1089538f45866cf5","type":"function","z":"58532bd4fd04eec0","name":"Write Front door lock variable to global.front_door_lock_status","func":"if (msg.payload == \"locked\") {\n    global.set(\"front_door_lock_status\",\"locked\")\n} else {    \n    global.set(\"front_door_lock_status\",\"unlocked\")\n}\nreturn msg; \n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":970,"y":1120,"wires":[[]]},{"id":"9d41272a3989f58e","type":"function","z":"58532bd4fd04eec0","name":"Write gym back door left open variable to global.front_door_lock_status","func":"if (msg.payload == \"off\") {\n    global.set(\"gym_back_door_left_open_status\",\"closed\")\n} else {    \n    global.set(\"gym_back_door_left_open_status\",\"open\")\n}\nreturn msg; \n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":990,"y":1180,"wires":[[]]},{"id":"d0fdd5ba9e85d44c","type":"function","z":"58532bd4fd04eec0","name":"Write gym back door right open variable to global.front_door_lock_status","func":"if (msg.payload == \"off\") {\n    global.set(\"gym_back_door_right_open_status\",\"closed\")\n} else {    \n    global.set(\"gym_back_door_right_open_status\",\"open\")\n}\nreturn msg; \n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1000,"y":1240,"wires":[[]]},{"id":"4cddb02641d7ae59","type":"function","z":"58532bd4fd04eec0","name":"Write jarvis door lock variable to global.jarvis_lock_status","func":"if (msg.payload == \"locked\") {\n    global.set(\"jarvis_door_lock_status\",\"locked\")\n} else {    \n    global.set(\"jarvis_door_lock_status\",\"unlocked\")\n}\nreturn msg; \n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":950,"y":1300,"wires":[[]]},{"id":"b3f9b41e4ffb43a8","type":"api-call-service","z":"58532bd4fd04eec0","name":"Set house secure boolean to On","server":"2620ec24.eeb984","version":3,"debugenabled":false,"service_domain":"homeassistant","service":"turn_on","entityId":"input_boolean.house_secure","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1490,"y":1160,"wires":[[]]},{"id":"e8d8937005ba7f3a","type":"api-call-service","z":"58532bd4fd04eec0","name":"Set house secure boolean to Off","server":"2620ec24.eeb984","version":3,"debugenabled":false,"service_domain":"homeassistant","service":"turn_on","entityId":"input_boolean.house_secure","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1490,"y":1240,"wires":[[]]},{"id":"2620ec24.eeb984","type":"server","name":"Home Assistant","version":1,"legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

does the message being sent to the function nodes identify the door or window?

Also I see in your flow the front door shows 'locked' and 'unlocked' while the gym doors are 'open' and 'closed'. Is that correct?

I'm confused about your terminology:

[NOTE:] this uses the new link call node in NR v2.1.0

@scottda Darren, your situation intrigued me and I played around for a bit and came up with this expandable solution.

[{"id":"b946b6d6f1384bbd","type":"inject","z":"397c2f459ec16f88","name":"Front door unlocked","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"Front door","payload":"unlocked","payloadType":"str","x":150,"y":200,"wires":[["ebe70eb3bfe15eeb"]]},{"id":"5bdafdb6d195bc3f","type":"inject","z":"397c2f459ec16f88","name":"Front door locked","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"Front door","payload":"locked","payloadType":"str","x":140,"y":240,"wires":[["ebe70eb3bfe15eeb"]]},{"id":"093316f2d930fb91","type":"inject","z":"397c2f459ec16f88","name":"gym back door left open","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"gym back door left","payload":"open","payloadType":"str","x":170,"y":300,"wires":[["ebe70eb3bfe15eeb"]]},{"id":"0794bc9e30ea9991","type":"inject","z":"397c2f459ec16f88","name":"gym back door left closed","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"gym back door left","payload":"closed","payloadType":"str","x":170,"y":340,"wires":[["ebe70eb3bfe15eeb"]]},{"id":"a8ae0244601876fb","type":"inject","z":"397c2f459ec16f88","name":"gym back door right open","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"gym back door right","payload":"open","payloadType":"str","x":170,"y":400,"wires":[["ebe70eb3bfe15eeb"]]},{"id":"e7886559a21e6046","type":"inject","z":"397c2f459ec16f88","name":"gym back door right closed","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"gym back door right","payload":"closed","payloadType":"str","x":170,"y":440,"wires":[["ebe70eb3bfe15eeb"]]},{"id":"801517e98c9ba6fa","type":"inject","z":"397c2f459ec16f88","name":" jarvis door unlocked","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":" jarvis door","payload":"unlocked","payloadType":"str","x":150,"y":500,"wires":[["ebe70eb3bfe15eeb"]]},{"id":"153ce5f9350b6398","type":"inject","z":"397c2f459ec16f88","name":" jarvis door locked","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":" jarvis door","payload":"locked","payloadType":"str","x":140,"y":540,"wires":[["ebe70eb3bfe15eeb"]]},{"id":"feb31e1bca38aa94","type":"inject","z":"397c2f459ec16f88","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"doors","payloadType":"global","x":170,"y":120,"wires":[["b554871717464e74"]]},{"id":"ebe70eb3bfe15eeb","type":"link call","z":"397c2f459ec16f88","name":"Set status in global","links":["d40b527dcbde48df"],"timeout":"30","x":530,"y":340,"wires":[["a8f6c839a13a0c28"]]},{"id":"d40b527dcbde48df","type":"link in","z":"397c2f459ec16f88","name":"Set Status","links":[],"x":380,"y":480,"wires":[["252d653f926ccff9"]],"l":true},{"id":"ca2a8928d1fe6ca8","type":"link out","z":"397c2f459ec16f88","name":"return","mode":"return","links":[],"x":830,"y":480,"wires":[],"l":true},{"id":"252d653f926ccff9","type":"function","z":"397c2f459ec16f88","name":"","func":"// get the global 'doors' object or itinilize it if it doesn't exist\nlet doors = global.get('doors') || {}\n\n// get the door name from msg.topic\nlet door_name = msg.topic\n\n// get this doors object of initilize it\n//let this_door = doors.door_name ||{'name': msg.topic, 'status': msg.payload}\nlet this_door = doors.door_name ||{'status': msg.payload}\n\n// check the door status and set it in teh objct\nif ( (msg.payload == 'open') || (msg.payload == 'unlocked') ) {\n    this_door.state = 0\n    this_door.status = msg.payload\n} else if ( (msg.payload == 'closed') || (msg.payload == 'locked') ) {\n    this_door.state = 1    \n    this_door.status = msg.payload\n} else {\n    // an unknown status has arrived - send a warning\n    node.warn('unknown status for '+ msg.topic)\n    return null\n}\n\n// update the 'doors' variable\ndoors[door_name] = this_door\n// update the 'doors' global\nglobal.set('doors', doors)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":480,"wires":[["ca2a8928d1fe6ca8"]]},{"id":"a8f6c839a13a0c28","type":"debug","z":"397c2f459ec16f88","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":760,"y":340,"wires":[]},{"id":"3c5671db2c18c284","type":"debug","z":"397c2f459ec16f88","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":790,"y":120,"wires":[]},{"id":"ddd7971942421d43","type":"comment","z":"397c2f459ec16f88","name":"This flow runs at a set interval and checks to sse that all doors are locked/closed ","info":"","x":430,"y":60,"wires":[]},{"id":"ab37f81aefc3e35f","type":"comment","z":"397c2f459ec16f88","name":"'Set Status' This flow sets the global with the status of each door ","info":"","x":660,"y":420,"wires":[]},{"id":"51b224860c6ee555","type":"comment","z":"397c2f459ec16f88","name":"This flow takes the input status of the doors and calls the 'Set Status' flow","info":"","x":710,"y":260,"wires":[]},{"id":"b554871717464e74","type":"function","z":"397c2f459ec16f88","name":"","func":"function delay(time) {\n  return new Promise(resolve => setTimeout(resolve, time));\n}\n\n\nconst doors =  msg.payload\nmsg.payload = \"system secure\"\n\nfor (let key in doors) {\n//    node.warn(\"processing\" key);\n//    node.warn(\"door: \" + key + \" state=\" + doors[key][\"state\"]);\n    if (doors[key][\"state\"] == 0) {\n        msg.payload = \"security breach: \"+ key;\n        node.send(msg);\n    }\n}\n\nreturn;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":440,"y":120,"wires":[["3c5671db2c18c284"]]}]

It uses a single object called 'doors' and for each input message, it uses the msg.topic as the door name of an object in the doors object. It checks msg.payload for 'open' or 'unlocked' and 'closed' or 'locked' and sets 'state' to 0 or 1. 1 means 'closed/locked' and 0 means 'open/unlocked'.

The top flow goes thru the doors object and any 0 it finds causes it to send a msg.payload of "security breach" with the door name (ok that might be a little dramatic)

You should find it easily adaptable.

thanks @zenofmud for all the time you have put into this so far, really appreciate your help. In the first of your last two posts above, yep you got me there...thats a typo from last night, the code is correct but i had forgot to update the name from lock/unlock status to open/closed status

But onto the interesting bit you posted below. I always find it easier to import in then follow the logic. I tried to import in but it does not like your "Set status in global" node...tells me that i have a missing node type called 'link call' ????

any suggestions?

Yes...

You must be using old version of node-red

1 Like

You could just stick the function node where the 'unknown: link call' is, or add a link-out to go to 'Set Status' and a link-out to the debuug node.

I was just looking for a chance to use the new node :grin:

ha ha ha, chance to use new code!

not showing an update on node red but no problem, will check out the code. thanks

Ahhh, your running Home Assistant. Just stick the function node where the link-call node would go so you can play with the flows.

p.s. I take it that this is for a school??

@zenofmud, thank you so much for trying to help me. I am reading your function code and to be frank, its just outside of my understanding. Given that i need to maintain this is i may have to look for another way of doing it.
Its not for a school however, its my home (maybe the gym bit threw you off? its a small home gym on the back of the house).
I really appreciate you trying to help but on this occasion im going to have to admit defeat and try something else (although your IF syntax in the function may help me with my original idea at tackling this)
thanks again and i wish i had these coding skills!!!