ledgardener / HomeAssistantYT

18 stars 9 forks source link

Feature Request: Add master switch for humidity #1

Open Naninani opened 3 years ago

Naninani commented 3 years ago

Hey @ledgardener,

Thx for all the great work you put in your automation, videos as well as sharing your setup.

I thought I could contribute to your work with a feature request to add master switch for the humidity control.

Case: Trigger the node-red automation for the humidifier only if the master switch is on. If its off, check if the humidifier is running - if on - then turn it off. Imo this is useful in case where you test things or you want to completely turn off the humidity control.

I'm not an expert in node-red but I managed to write something up that you may find useful:

Flow:

  1. I added a new "input" switch from Helpers and hook it up to the code you shared in ur last video.
  2. Changed the "join" to expect 4 payloads instead of 3. image
  3. In case the master switch is off - the automation for switching on the humidifier is not executed at all. Also it checks if the humidifier is on and turns it off. image

Node-Red Code:

[{"id":"cc4e372f.cdd038","type":"tab","label":"Humidity Control","disabled":false,"info":""},{"id":"97a547a5.17a228","type":"server-state-changed","z":"cc4e372f.cdd038","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.humidity_target","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":190,"y":40,"wires":[["e6988b76.9d4468"]]},{"id":"35daa761.f92798","type":"server-state-changed","z":"cc4e372f.cdd038","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.humidity_tolerance","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":200,"y":100,"wires":[["e6988b76.9d4468"]]},{"id":"85ccba4f.e04ab8","type":"server-state-changed","z":"cc4e372f.cdd038","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.grow_room_humidity","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":190,"y":160,"wires":[["e6988b76.9d4468"]]},{"id":"e6988b76.9d4468","type":"join","z":"cc4e372f.cdd038","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":490,"y":100,"wires":[["4060373c.7889f8","eaf892c7.93d24"]]},{"id":"eaf892c7.93d24","type":"function","z":"cc4e372f.cdd038","name":"","func":"if (msg.payload[\"sensor.grow_room_humidity\"] < (msg.payload[\"input_number.humidity_target\"] - msg.payload[\"input_number.humidity_tolerance\"])) {\n    return [msg, null];\n}\n\nelse if (msg.payload[\"sensor.grow_room_humidity\"] > (msg.payload[\"input_number.humidity_target\"] + msg.payload[\"input_number.humidity_tolerance\"])) {\n    return [null, msg];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":640,"y":100,"wires":[["12b8eae4.fcc8f5"],["8c7780bd.502f6"]]},{"id":"72f41520.77e4bc","type":"api-call-service","z":"cc4e372f.cdd038","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_on","entityId":"switch.humidifier","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1110,"y":60,"wires":[[]]},{"id":"af1ee251.72b58","type":"api-call-service","z":"cc4e372f.cdd038","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.humidifier","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1110,"y":120,"wires":[[]]},{"id":"12b8eae4.fcc8f5","type":"api-current-state","z":"cc4e372f.cdd038","name":"","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.humidifier","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":870,"y":60,"wires":[["72f41520.77e4bc"],[]]},{"id":"8c7780bd.502f6","type":"api-current-state","z":"cc4e372f.cdd038","name":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.humidifier","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":870,"y":120,"wires":[["af1ee251.72b58"],[]]},{"id":"8eb43631.06a548","type":"api-current-state","z":"cc4e372f.cdd038","name":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.humidifier","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":570,"y":220,"wires":[["46600dca.8f7e44"],[]]},{"id":"46600dca.8f7e44","type":"api-call-service","z":"cc4e372f.cdd038","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.humidifier","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":810,"y":220,"wires":[[]]},{"id":"4060373c.7889f8","type":"debug","z":"cc4e372f.cdd038","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":530,"y":160,"wires":[]},{"id":"9c93a878.9b60e8","type":"server-state-changed","z":"cc4e372f.cdd038","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.humidity_control","entityidfiltertype":"exact","outputinitially":true,"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,"x":200,"y":220,"wires":[["e6988b76.9d4468"],["8eb43631.06a548"]]}]
ledgardener commented 3 years ago

Hey, thanks for pasting this over! I like the idea. I think I'll add it to the part 6 folder as an improved version. That way, the original is there so people aren't confused when the one they download doesn't match the one in the video, but this is also there as a better option. Thank you for taking the time to put this forward.

Regarding the implementation, I think we could save a few blocks just by modifying the function node:

image

image

[{"id":"4c00655e.4cd224","type":"tab","label":"Humidifier Control","disabled":false,"info":""},{"id":"53ee927a.9a1434","type":"api-call-service","z":"4c00655e.4cd224","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_on","entityId":"switch.tplink1","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1220,"y":100,"wires":[[]]},{"id":"798972f9.e58d44","type":"api-call-service","z":"4c00655e.4cd224","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.tplink1","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1210,"y":160,"wires":[[]]},{"id":"d369ec2b.f240d8","type":"function","z":"4c00655e.4cd224","name":"","func":"if (msg.payload[\"input_boolean.humidity_control\"] == \"on\") {\n if (msg.payload[\"sensor.ruuvi_humidity_4x4\"] < (msg.payload[\"input_number.humidity_target\"] - msg.payload[\"input_number.humidity_tolerance\"])) {\n return [msg, null];\n } \n else if (msg.payload[\"sensor.ruuvi_humidity_4x4\"] > (msg.payload[\"input_number.humidity_target\"] + msg.payload[\"input_number.humidity_tolerance\"])) {\n return [null, msg];\n }\n}\n \nelse {\n return [null, msg];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":700,"y":140,"wires":[["5c9e479e.918e9"],["e1a78bd6.7f497"]]},{"id":"5c9e479e.918e9","type":"api-current-state","z":"4c00655e.4cd224","name":"","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.tplink1","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":978,"y":95,"wires":[["53ee927a.9a1434"],[]]},{"id":"e1a78bd6.7f497","type":"api-current-state","z":"4c00655e.4cd224","name":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.tplink1","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":980,"y":160,"wires":[["798972f9.e58d44"],[]]},{"id":"7f3d8042.3d10a8","type":"debug","z":"4c00655e.4cd224","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":710,"y":220,"wires":[]},{"id":"9df42140.57b78","type":"server-state-changed","z":"4c00655e.4cd224","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.humidity_target","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":220,"y":80,"wires":[["d7b1ed4.41dcb9"]]},{"id":"4a2385a4.b1bad4","type":"server-state-changed","z":"4c00655e.4cd224","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.humidity_tolerance","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":230,"y":140,"wires":[["d7b1ed4.41dcb9"]]},{"id":"c9aef9a5.51ad18","type":"server-state-changed","z":"4c00655e.4cd224","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.ruuvi_humidity_4x4","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":210,"y":200,"wires":[["d7b1ed4.41dcb9"]]},{"id":"d7b1ed4.41dcb9","type":"join","z":"4c00655e.4cd224","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":530,"y":140,"wires":[["7f3d8042.3d10a8","d369ec2b.f240d8"]]},{"id":"fa6afc06.a11d18","type":"server-state-changed","z":"4c00655e.4cd224","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.humidity_control","entityidfiltertype":"exact","outputinitially":true,"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":220,"y":260,"wires":[["d7b1ed4.41dcb9"]]}]

Naninani commented 3 years ago

I'm not an expert into node-red, but would what you posted actually work? If the "join" node expects 4 messages parts and the master switch is off the function would not be executed at all - thus not evaluating the conditions. If "join" expect 3 messages, would the one from the master switch be passed to the function? If yes then what you posted would work. However I think its better not to run/evaluate the function at all if the master switch is off - system would use less resources to compute.

I created one more flow with a reverse logic to control the fans in my control box - that might be useful as well. I use the flow below to trigger a fan if the temp in my control box is above a threshold.

[{"id":"73256eb1.6c7d7","type":"tab","label":"Control Box Temp Control","disabled":false,"info":""},{"id":"dbe49517.b06198","type":"server-state-changed","z":"73256eb1.6c7d7","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.control_box_temp_target","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":220,"y":40,"wires":[["8d6f656.7730898"]]},{"id":"1bc9b366.f46f6d","type":"server-state-changed","z":"73256eb1.6c7d7","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.control_box_temp_tolerance","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":230,"y":100,"wires":[["8d6f656.7730898"]]},{"id":"39df57f4.aa43c8","type":"server-state-changed","z":"73256eb1.6c7d7","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.control_box_temperature","entityidfiltertype":"exact","outputinitially":false,"state_type":"num","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":200,"y":160,"wires":[["8d6f656.7730898"]]},{"id":"8d6f656.7730898","type":"join","z":"73256eb1.6c7d7","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":550,"y":100,"wires":[["e8a0762b.146438","fe1e3d9e.30eb3"]]},{"id":"fe1e3d9e.30eb3","type":"function","z":"73256eb1.6c7d7","name":"","func":"if (msg.payload[\"sensor.control_box_temperature\"] > (msg.payload[\"input_number.control_box_temp_target\"] + msg.payload[\"input_number.control_box_temp_tolerance\"])) {\n    return [msg, null];\n}\n\nelse if (msg.payload[\"sensor.control_box_temperature\"] < (msg.payload[\"input_number.control_box_temp_target\"] - msg.payload[\"input_number.control_box_temp_tolerance\"])) {\n    return [null, msg];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":700,"y":100,"wires":[["b918183a.7d5188"],["cd4b6009.a0a14"]]},{"id":"d4e69444.876308","type":"api-call-service","z":"73256eb1.6c7d7","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_on","entityId":"switch.control_box_fan","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1210,"y":60,"wires":[["91085891.3e83a8"]]},{"id":"70e5eab4.c9c654","type":"api-call-service","z":"73256eb1.6c7d7","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.control_box_fan","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1210,"y":120,"wires":[["91085891.3e83a8"]]},{"id":"b918183a.7d5188","type":"api-current-state","z":"73256eb1.6c7d7","name":"","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.control_box_fan","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":950,"y":60,"wires":[["d4e69444.876308"],[]]},{"id":"cd4b6009.a0a14","type":"api-current-state","z":"73256eb1.6c7d7","name":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.control_box_fan","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":950,"y":120,"wires":[["70e5eab4.c9c654"],[]]},{"id":"151166c3.6f3869","type":"api-current-state","z":"73256eb1.6c7d7","name":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.control_box_fan","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":630,"y":220,"wires":[["e8cfec61.423d1"],[]]},{"id":"e8cfec61.423d1","type":"api-call-service","z":"73256eb1.6c7d7","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.control_box_fan","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":890,"y":220,"wires":[["f5392a66.653fd8"]]},{"id":"e8a0762b.146438","type":"debug","z":"73256eb1.6c7d7","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":590,"y":160,"wires":[]},{"id":"e8eb01d1.204c2","type":"server-state-changed","z":"73256eb1.6c7d7","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.control_box_temp_control","entityidfiltertype":"exact","outputinitially":true,"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,"x":230,"y":220,"wires":[["8d6f656.7730898"],["151166c3.6f3869"]]},{"id":"91085891.3e83a8","type":"debug","z":"73256eb1.6c7d7","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1490,"y":80,"wires":[]},{"id":"f5392a66.653fd8","type":"debug","z":"73256eb1.6c7d7","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1110,"y":220,"wires":[]}]
ledgardener commented 3 years ago

It does indeed work. I left the count at 3 on the join rather than bumping it to 4. The only reason the input boolean even feeds the join is to capture its state change and force the function to re-evaluate when you toggle the master. Try it out and you'll see it does, in fact, work. I'll have a gander at your other one.

Edit: Looks good! I think it'd be a good idea to eliminate the duplicate current state and call service blocks, and just wire new block to the existing ones like this:

image

Naninani commented 3 years ago

Awesome, thats a good idea - improves the flow!

I have another one that could eliminate the "current_state" checks - those could be built into the function as well (dono the syntax on how to check the state there thought)

Something like:

let cbTemp = msg.payload["sensor.control_box_temperature"];
let cbTempTarget = msg.payload["input_number.control_box_temp_target"];
let cbTempTolerance = msg.payload["input_number.control_box_temp_tolerance"];
let cbSwitchFan = (the state of the switch you want to check if its on or of);

if (
  cbTemp > (cbTempTarget + cbTempTolerance)
  && cbSwitchFan === 'off'
) {
  return [msg, null];
} else if (
  cbTemp < (cbTempTarget - cbTempTolerance)
  && cbSwitchFan === 'on'
) {
  return [null, msg];
}
Naninani commented 3 years ago

My original flow was buggy and not honoring the state of the master switch. Based on your suggestions this is what I ended up and its working ok.

Humidity:

[{"id":"cc4e372f.cdd038","type":"tab","label":"Grow Room Humidity Control","disabled":false,"info":""},{"id":"97a547a5.17a228","type":"server-state-changed","z":"cc4e372f.cdd038","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.humidity_target","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":190,"y":40,"wires":[["e6988b76.9d4468"]]},{"id":"35daa761.f92798","type":"server-state-changed","z":"cc4e372f.cdd038","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.humidity_tolerance","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":200,"y":100,"wires":[["e6988b76.9d4468"]]},{"id":"85ccba4f.e04ab8","type":"server-state-changed","z":"cc4e372f.cdd038","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.grow_room_humidity","entityidfiltertype":"exact","outputinitially":false,"state_type":"num","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":190,"y":160,"wires":[["e6988b76.9d4468"]]},{"id":"e6988b76.9d4468","type":"join","z":"cc4e372f.cdd038","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":490,"y":100,"wires":[["4060373c.7889f8","eaf892c7.93d24"]]},{"id":"eaf892c7.93d24","type":"function","z":"cc4e372f.cdd038","name":"","func":"let grHumidity = msg.payload[\"sensor.grow_room_humidity\"];\nlet grHumidityTarget = msg.payload[\"input_number.humidity_target\"];\nlet grHumidityTolerance = msg.payload[\"input_number.humidity_tolerance\"];\nlet grHumidityControl = msg.payload[\"input_boolean.humidity_control\"];\n\nif (grHumidityControl === 'on') {\n    if (grHumidity < (grHumidityTarget + grHumidityTolerance)) {\n        return [msg, null];\n    } else if (grHumidity > (grHumidityTarget - grHumidityTolerance)) {\n        return [null, msg];\n    }\n} else {\n    return [null, msg];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":640,"y":100,"wires":[["12b8eae4.fcc8f5"],["8c7780bd.502f6"]]},{"id":"72f41520.77e4bc","type":"api-call-service","z":"cc4e372f.cdd038","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_on","entityId":"switch.humidifier","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1110,"y":60,"wires":[[]]},{"id":"af1ee251.72b58","type":"api-call-service","z":"cc4e372f.cdd038","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.humidifier","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1110,"y":120,"wires":[[]]},{"id":"12b8eae4.fcc8f5","type":"api-current-state","z":"cc4e372f.cdd038","name":"","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.humidifier","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":870,"y":60,"wires":[["72f41520.77e4bc"],[]]},{"id":"8c7780bd.502f6","type":"api-current-state","z":"cc4e372f.cdd038","name":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.humidifier","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":870,"y":120,"wires":[["af1ee251.72b58"],[]]},{"id":"4060373c.7889f8","type":"debug","z":"cc4e372f.cdd038","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":510,"y":140,"wires":[]},{"id":"9c93a878.9b60e8","type":"server-state-changed","z":"cc4e372f.cdd038","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.humidity_control","entityidfiltertype":"exact","outputinitially":true,"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":200,"y":220,"wires":[["e6988b76.9d4468"]]}]

Temp:

[{"id":"73256eb1.6c7d7","type":"tab","label":"Control Box Temp Control","disabled":false,"info":""},{"id":"dbe49517.b06198","type":"server-state-changed","z":"73256eb1.6c7d7","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.control_box_temp_target","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":220,"y":40,"wires":[["8d6f656.7730898"]]},{"id":"1bc9b366.f46f6d","type":"server-state-changed","z":"73256eb1.6c7d7","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.control_box_temp_tolerance","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","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":230,"y":100,"wires":[["8d6f656.7730898"]]},{"id":"39df57f4.aa43c8","type":"server-state-changed","z":"73256eb1.6c7d7","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.control_box_temperature","entityidfiltertype":"exact","outputinitially":false,"state_type":"num","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":200,"y":160,"wires":[["8d6f656.7730898"]]},{"id":"8d6f656.7730898","type":"join","z":"73256eb1.6c7d7","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":550,"y":100,"wires":[["e8a0762b.146438","fe1e3d9e.30eb3"]]},{"id":"fe1e3d9e.30eb3","type":"function","z":"73256eb1.6c7d7","name":"","func":"let cbTemp = msg.payload[\"sensor.control_box_temperature\"];\nlet cbTempTarget = msg.payload[\"input_number.control_box_temp_target\"];\nlet cbTempTolerance = msg.payload[\"input_number.control_box_temp_tolerance\"];\nlet cbTempControl = msg.payload[\"input_boolean.control_box_temp_control\"];\n\nif (cbTempControl === 'on') {\n    if (cbTemp > (cbTempTarget + cbTempTolerance)) {\n        return [msg, null];\n    } else if (cbTemp < (cbTempTarget - cbTempTolerance)) {\n        return [null, msg];\n    }\n} else {\n    return [null, msg];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":700,"y":100,"wires":[["b918183a.7d5188"],["cd4b6009.a0a14"]]},{"id":"d4e69444.876308","type":"api-call-service","z":"73256eb1.6c7d7","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_on","entityId":"switch.control_box_fan","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1210,"y":60,"wires":[[]]},{"id":"70e5eab4.c9c654","type":"api-call-service","z":"73256eb1.6c7d7","name":"","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.control_box_fan","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1210,"y":120,"wires":[[]]},{"id":"b918183a.7d5188","type":"api-current-state","z":"73256eb1.6c7d7","name":"","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.control_box_fan","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":950,"y":60,"wires":[["d4e69444.876308"],[]]},{"id":"cd4b6009.a0a14","type":"api-current-state","z":"73256eb1.6c7d7","name":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.control_box_fan","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":950,"y":120,"wires":[["70e5eab4.c9c654"],[]]},{"id":"e8a0762b.146438","type":"debug","z":"73256eb1.6c7d7","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":570,"y":140,"wires":[]},{"id":"e8eb01d1.204c2","type":"server-state-changed","z":"73256eb1.6c7d7","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.control_box_temp_control","entityidfiltertype":"exact","outputinitially":true,"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":230,"y":220,"wires":[["8d6f656.7730898"]]}]
jaysalazar commented 3 years ago

I tried the code that @Naninani posted however I didn't quite work for me.

I am using the code by @ledgardener and works great. Thanks to the both of you.

I actually have been wanting a "Master Control" option for quite some time. Thank @Naninani for brining this up.