Help with detecting state of 4 switches and only performing action if all four are off

I am having some issues coming up with a flow for my greenhouse zones.

I have 4 zones setup via smart solenoids and a master water solenoid, so technically 5 zones. If you turn on any of the four zones, the master will turn on.

If I turn off 1 zone but still have more than 1 zone still on, the master remains on, but if all zones are off than I want the master solenoid to switch to turn off.

At this stage, I am using the following but it does not seem to be giving me an accurate true/ false reading which makes me think I am probably doing this wrong.

This is the flow I have so far.

[{"id":"596aebd0.918ae4","type":"api-call-service","z":"812a8d9.718ce7","name":"water_off","server":"9444eca1.01d33","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.button_toggle","data":"","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1320,"y":500,"wires":[[]]},{"id":"2797832b.219a5c","type":"server-state-changed","z":"812a8d9.718ce7","name":"zone1_off","server":"9444eca1.01d33","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"switch.52087318e09806cb1d21","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"off","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,"x":120,"y":480,"wires":[["87b28952.8570a8"],[]]},{"id":"52a27c7c.256504","type":"server-state-changed","z":"812a8d9.718ce7","name":"zone2_off","server":"9444eca1.01d33","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"switch.52087318e09806cbc52d","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"off","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,"x":120,"y":540,"wires":[["6b3d8d4e.dac3c4"],[]]},{"id":"87b28952.8570a8","type":"api-current-state","z":"812a8d9.718ce7","name":"Detection Zone1","server":"9444eca1.01d33","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.52087318e09806cb1d21","state_type":"str","state_location":"","override_payload":"msg","entity_location":"","override_data":"none","blockInputOverrides":false,"x":380,"y":480,"wires":[["9bf7a176.4169d"]]},{"id":"6b3d8d4e.dac3c4","type":"api-current-state","z":"812a8d9.718ce7","name":"Detection Zone2","server":"9444eca1.01d33","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.52087318e09806cbc52d","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"","override_data":"none","blockInputOverrides":false,"x":380,"y":540,"wires":[["8d618a9d.a0a838"]]},{"id":"33b4acf.7caaa54","type":"function","z":"812a8d9.718ce7","name":"","func":"var z1 = global.get(\"zone1\");\nvar z2 = global.get(\"zone2\");\nvar z3 = global.get(\"zone3\");\nvar z4 = global.get(\"zone4\");\n\nif (z1 == \"off\" && z2 == \"off\"){\n msg.payload = \"true\"\n}\n\nelse{ \n msg.payload = \"false\"\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":880,"y":500,"wires":[["10a163b1.3c0f9c"]]},{"id":"10a163b1.3c0f9c","type":"switch","z":"812a8d9.718ce7","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"true","vt":"str"},{"t":"cont","v":"false","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1090,"y":500,"wires":[["596aebd0.918ae4"],[]]},{"id":"9bf7a176.4169d","type":"function","z":"812a8d9.718ce7","name":"Set Z1 variable","func":"global.set(\"zone1\",msg.payload);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":640,"y":480,"wires":[["33b4acf.7caaa54"]]},{"id":"8d618a9d.a0a838","type":"function","z":"812a8d9.718ce7","name":"Set z2 variable","func":"global.set(\"zone2\",msg.payload);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":640,"y":540,"wires":[["33b4acf.7caaa54"]]},{"id":"9444eca1.01d33","type":"server","name":"Home Assistant","legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":false}]

I think my logic might be wrong. I am still quite new to using NodeRed. Has anyone done something similar that they might be able to explain and share?

Hi there, I think, you can do this easily by creating a group out of the 4 zones in home assistant and then using a simple automation. i,e if you are ok with using HA automations than nodered.

First make a group by copying this to HA config.

group:
  solenoids:
    name: Solenoids
    entities:
      - switch.solenoid1
      - switch.solenoid2
      - switch.solenoid3
      - switch.solenoid4

Now we have to make an automation.

alias: Solenoid control
description: ''
mode: single
trigger:
  - platform: state
    entity_id: group.solenoids
condition: []
action:
  - choose:
      - conditions:
          - condition: state
            entity_id: group.solenoids
            state: 'on'
        sequence:
          - service: switch.turn_on
            target:
              entity_id: switch.master_solenoid
      - conditions:
          - condition: state
            entity_id: group.solenoids
            state: 'off'
        sequence:
          - service: switch.turn_off
            target:
              entity_id: switch.master_solenoid
    default: []

You have to change the entity_id of each and every solenoid component in accordance to your system. If you need any more help please do ask.

Hey thanks for the suggestion. I just plugged that into HA, however I think line 22:

you can’t have off. I think it’s expecting a time maybe? I got this error, which I think is what it’s talking about maybe?

Yep I just saw that mistake.
Off should be in state: not for:

Also I’d make the default action off. Rather than having a second condition to check if it’s off.

I have made a change to the code, please copy it now and see

alias: Solenoid control
description: ''
mode: single
trigger:
  - platform: state
    entity_id: group.solenoids
condition: []
action:
  - choose:
      - conditions:
          - condition: state
            entity_id: group.solenoids
            state: 'on'
        sequence:
          - service: switch.turn_on
            target:
              entity_id: switch.master_solenoid
    default:
      - service: switch.turn_off
        target:
          entity_id: switch.master_solenoid

I’m not sure how a group handles an entity going unavailable? Does the group then go unavailable?
If so using the default option to switch off gives you a failsafe.

That got it. Wow, that was easy… Thank you so much. I have been trying to figure this out for most of today… I cant believe how easy that was.

You can achieve this in NR with a template node too. Something like this logic would do the trick (Not live tested as I have mocked up the entity ids.

[{"id":"81203263.8e755","type":"tab","label":"Master + Child","disabled":false,"info":""},{"id":"63cfac18.d11a64","type":"server-state-changed","z":"81203263.8e755","name":"Zone 1 off","server":"525b6e8f.855cf","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"switch.greenhouse1","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":160,"y":180,"wires":[["96a94460.0b61f8"]]},{"id":"96a94460.0b61f8","type":"api-render-template","z":"81203263.8e755","name":"If All Zones are Off","server":"525b6e8f.855cf","template":"{% if is_state(\"switch.greenhouse1\", \"off\") and\nis_state(\"switch.greenhouse2\", \"off\")\nis_state(\"switch.greenhouse3\", \"off\")\nis_state(\"switch.greenhouse4\", \"off\") %}yes\n{%-else %}no{% endif %}","resultsLocation":"payload","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":370,"y":260,"wires":[["ddc10266.b261e"]]},{"id":"39f66dd3.8526e2","type":"server-state-changed","z":"81203263.8e755","name":"Zone 2 off","server":"525b6e8f.855cf","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"switch.greenhouse2","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":160,"y":240,"wires":[["96a94460.0b61f8"]]},{"id":"fa7a81c7.d975e","type":"server-state-changed","z":"81203263.8e755","name":"Zone 3 off","server":"525b6e8f.855cf","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"switch.greenhouse3","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":160,"y":300,"wires":[["96a94460.0b61f8"]]},{"id":"7758c93c.4a44b8","type":"server-state-changed","z":"81203263.8e755","name":"Zone 4 off","server":"525b6e8f.855cf","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"switch.greenhouse4","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":160,"y":360,"wires":[["96a94460.0b61f8"]]},{"id":"ddc10266.b261e","type":"switch","z":"81203263.8e755","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"yes","vt":"str"},{"t":"eq","v":"no","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":260,"wires":[["b3b4ed17.b0e64"],[]]},{"id":"fdbc3daa.6328","type":"comment","z":"81203263.8e755","name":"If No Then Do Nothing","info":"","x":720,"y":320,"wires":[]},{"id":"b3b4ed17.b0e64","type":"api-call-service","z":"81203263.8e755","name":"Zone 2 Turn off","server":"525b6e8f.855cf","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.greenhouseMasterZone","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":740,"y":220,"wires":[[]]},{"id":"f829599b.77efb8","type":"comment","z":"81203263.8e755","name":"If Yes Then Turn off Master Switch","info":"","x":740,"y":160,"wires":[]},{"id":"525b6e8f.855cf","type":"server","name":"Home Assistant","legacy":false,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

So I gave your NR flow a go. However I am getting a Status Code 400 when it attemptes to trigger the template. Screenshot from 2021-04-06 21-15-23

You can put them in a group, or use boolean logic in NR: https://flows.nodered.org/node/node-red-contrib-boolean-logic-ultimate

Suggest troubleshooting it in your Developer Tools /developer-tools/template. I’ve also updated the template node that was missing a couple of and conditions.

[{"id":"81203263.8e755","type":"tab","label":"Master + Child","disabled":false,"info":""},{"id":"63cfac18.d11a64","type":"server-state-changed","z":"81203263.8e755","name":"Zone 1 off","server":"525b6e8f.855cf","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"switch.greenhouse1","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":160,"y":180,"wires":[["96a94460.0b61f8"]]},{"id":"96a94460.0b61f8","type":"api-render-template","z":"81203263.8e755","name":"If All Zones are Off","server":"525b6e8f.855cf","template":"{% if is_state(\"switch.greenhouse1\", \"off\") and\nis_state(\"switch.greenhouse2\", \"off\") and\nis_state(\"switch.greenhouse3\", \"off\") and\nis_state(\"switch.greenhouse4\", \"off\") %}yes\n{%-else %}no{% endif %}","resultsLocation":"payload","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":370,"y":260,"wires":[["ddc10266.b261e"]]},{"id":"39f66dd3.8526e2","type":"server-state-changed","z":"81203263.8e755","name":"Zone 2 off","server":"525b6e8f.855cf","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"switch.greenhouse2","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":160,"y":240,"wires":[["96a94460.0b61f8"]]},{"id":"fa7a81c7.d975e","type":"server-state-changed","z":"81203263.8e755","name":"Zone 3 off","server":"525b6e8f.855cf","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"switch.greenhouse3","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":160,"y":300,"wires":[["96a94460.0b61f8"]]},{"id":"7758c93c.4a44b8","type":"server-state-changed","z":"81203263.8e755","name":"Zone 4 off","server":"525b6e8f.855cf","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"switch.greenhouse4","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":160,"y":360,"wires":[["96a94460.0b61f8"]]},{"id":"ddc10266.b261e","type":"switch","z":"81203263.8e755","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"yes","vt":"str"},{"t":"eq","v":"no","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":260,"wires":[["b3b4ed17.b0e64"],[]]},{"id":"fdbc3daa.6328","type":"comment","z":"81203263.8e755","name":"If No Then Do Nothing","info":"","x":720,"y":320,"wires":[]},{"id":"b3b4ed17.b0e64","type":"api-call-service","z":"81203263.8e755","name":"Turn Off Master","server":"525b6e8f.855cf","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.greenhouseMasterZone","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":740,"y":220,"wires":[[]]},{"id":"f829599b.77efb8","type":"comment","z":"81203263.8e755","name":"If Yes Then Turn off Master Switch","info":"","x":740,"y":160,"wires":[]},{"id":"525b6e8f.855cf","type":"server","name":"Home Assistant","legacy":false,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

Edit: Feel free to drop your template node syntax back in here if you don’t have any luck.

Got it. :slight_smile: Trying the flow again. Stay tuned.

…and success!

Thank you @jward101 for your assistance.

1 Like

If you need to add a zone later, you need modifications in 2 places. I would sincerely think about using a group or the boolean logic node.

Yeah, I think that’s a good idea. I’m working on that now actually now I have the logic. Also, think it will be useful for determining watering schedules based on rainfall as well. I can put the different schedules into a group too.

I’ve added a zone-based weather sensitive NR irrigation routine over here too: Its been updated to use the newer BOM integration but it should get you on your way as well.

1 Like

you can check the state of four switches from a single trigger-state node