The right logic for this task

So not the sharpest programmer in the world... in fact not programmer. However I do like to make things, and have programmed some stuff before.

However, I am struggling with getting some logic right. I want to:

Make a system that, based on indoor/outdoor humidity, starts a ventilator.
I have so far made an bool variable that reads humidity data from my Netatmo weather station devices and toggles the the on/off variable. However, I'd like two more inputs to enter the script:
A) a dashboard controlled max time that the ventilator can run, regardless of whether it started due to humidity readings or by (B) a manual toggle.
B) a manual on/off toggle.

I have done it previously on an old Arduino with a super crappy code that I can hardly live with. Now I'm redoing it and I thought that maybe you peeps on the internet could find a minute to provide a few hints as to how that is best done...
My flow WIP: (note that I had to remove usr/pw info)

[{"id":"5dd2ed34.6894bc","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"83eb50e3.700aa","type":"inject","z":"5dd2ed34.6894bc","name":"","topic":"5 Minutes Timer","payload":"true","payloadType":"bool","repeat":"300","crontab":"","once":true,"onceDelay":"0.1","x":580,"y":280,"wires":[["5550ac86.74f474"]]},{"id":"5550ac86.74f474","type":"netatmo-dashboard","z":"5dd2ed34.6894bc","creds":"25b2494d.73122e","x":580,"y":340,"wires":[["d9d6c6cc.b17648"]]},{"id":"9ba10667.b50b8","type":"ui_gauge","z":"5dd2ed34.6894bc","name":"","group":"1a5ecff2.92b44","order":1,"width":"3","height":"2","gtype":"gage","title":"T Kælder","label":"°C","format":"{{value}}","min":"0","max":"40","colors":["#0432ff","#00fdff","#ff2600"],"seg1":"5","seg2":"15","x":820,"y":340,"wires":[]},{"id":"7563139b.e691cc","type":"ui_gauge","z":"5dd2ed34.6894bc","name":"","group":"b37cbe7b.05118","order":1,"width":"3","height":"2","gtype":"gage","title":"T Ude","label":"°C","format":"{{value}}","min":"0","max":"40","colors":["#0432ff","#00fdff","#ff2600"],"seg1":"5","seg2":"15","x":810,"y":460,"wires":[]},{"id":"635b2b58.8aec84","type":"ui_gauge","z":"5dd2ed34.6894bc","name":"","group":"b37cbe7b.05118","order":2,"width":"3","height":"2","gtype":"gage","title":"Luftfugtighed Ude","label":"%","format":"{{value}}","min":0,"max":"100","colors":["#00fa00","#fffc00","#ff2600"],"seg1":"50","seg2":"60","x":850,"y":500,"wires":[]},{"id":"d9d6c6cc.b17648","type":"function","z":"5dd2ed34.6894bc","name":"get Netatmo Data","func":"\n\nvar msg1 = {};\nvar msg2 = {};\nvar msg3 = {};\nvar msg4 = {};\nvar msg_AhK = {};\nvar msg_AhU = {};\n\n\nmsg1.payload = Number(msg.payload.compact.modules[0].temperature); //kælder\nmsg1.topic = 'Kælder';\nmsg2.payload = Number(msg.payload.compact.modules[0].Humidity); //Kælder\nmsg2.topic = 'Kælder';\nmsg3.payload = Number(msg.payload.compact.outdoor.temperature);\nmsg3.topic = 'Ude';\nmsg4.payload = Number(msg.payload.compact.outdoor.humidity);\nmsg4.topic = 'Ude';\n//msg_AhK.payload = (6.112 * 2.718281828459^((17.67 * msg1.payload)/(msg1.payload+243.5)) * msg2.payload * 2.1674)/(273.15+msg1.payload);\n//msg_AhK.payload = (6.112*(2.718281828459^((17.67 * msg1.payload)/(msg1.payload+243.5))) * msg2.payload * 2.1674)/(273.15+msg1.payload);\n\nmsg_AhK.payload =  Number(6.112* Math.pow(2.718281828459,((17.67 * msg1.payload)/(msg1.payload+243.5))) * msg2.payload * 2.1674)/(273.15+msg1.payload);\nmsg_AhK.topic = 'Kælder';\nmsg_AhU.payload =  Number(6.112* Math.pow(2.718281828459,((17.67 * msg3.payload)/(msg3.payload+243.5))) * msg4.payload * 2.1674)/(273.15+msg3.payload);\nmsg_AhU.topic = 'Ude';\n\nflow.set(\"AhK\", msg_AhK);\nflow.set(\"AhU\", msg_AhU);\n\nreturn [msg1,msg2,msg_AhK,msg3,msg4,msg_AhU];","outputs":6,"noerr":0,"x":590,"y":420,"wires":[["9ba10667.b50b8"],["735f73a6.cb5c84","f5869f70.a4834"],["892c221.fca67e","eca7aaa7.d4c7e8"],["7563139b.e691cc"],["635b2b58.8aec84","d7586f4.5a02e1"],["7653673f.39f42","eca7aaa7.d4c7e8"]]},{"id":"735f73a6.cb5c84","type":"ui_gauge","z":"5dd2ed34.6894bc","name":"","group":"1a5ecff2.92b44","order":2,"width":"3","height":"2","gtype":"gage","title":"Luftfugtighed Kælder","label":"%","format":"{{value}}","min":0,"max":"100","colors":["#00fa00","#fffc00","#ff2600"],"seg1":"50","seg2":"60","x":860,"y":380,"wires":[]},{"id":"892c221.fca67e","type":"ui_gauge","z":"5dd2ed34.6894bc","name":"","group":"1a5ecff2.92b44","order":3,"width":"0","height":"0","gtype":"compass","title":"Vandindhold Kælder (g/m3)","label":"g/m3","format":"{{value | number:1}}","min":0,"max":"25","colors":["#00b500","#e6e600","#ca3838"],"seg1":"8","seg2":"12","x":880,"y":420,"wires":[]},{"id":"7653673f.39f42","type":"ui_gauge","z":"5dd2ed34.6894bc","name":"","group":"b37cbe7b.05118","order":3,"width":"0","height":"0","gtype":"compass","title":"Vandindhold Ude (g/m3)","label":"g/m3","format":"{{value | number:1}}","min":0,"max":"25","colors":["#00b500","#e6e600","#ca3838"],"seg1":"8","seg2":"12","x":870,"y":540,"wires":[]},{"id":"f361a804.0ea4d","type":"function","z":"5dd2ed34.6894bc","name":"","func":"\nvar msg1 = {};\nvar msg2 = {};\nvar msg3 = {};\nvar msg4 = {};\nvar msg5 = {};\nvar msg6 = {};\nvar msg7 = {};\nmsg7.topic = 'On/Off'\n\nvar AhK = flow.get(\"AhK\");\nvar AhU = flow.get(\"AhU\");\nvar ahTol = flow.get(\"ahTol\");\n\nmsg1.payload = AhK.payload;\nmsg2.payload = AhU.payload;\nmsg4.payload = ahTol.payload;\nmsg5.payload = AhU.payload*(1+(ahTol.payload/100));\nmsg6.payload = AhU.payload-AhK.payload;\n\nif (AhK.payload > (msg5.payload) ) {\nmsg3.payload = true;\nhumOnoff = true;\nmsg7.payload = 20;\n}\nelse {\nmsg3.payload = false;\nhumOnoff =false;\nmsg7.payload = 0;\n\n}\n\n\n\nreturn [msg1, msg2, msg3, msg4, msg5, msg6, msg7];","outputs":7,"noerr":0,"x":502,"y":825,"wires":[["967df6b6.66d01"],["f95cc6b1.beeed"],["9f2359bf.354838"],["4c9de6d7.98bc9"],["d7cbd3ee.50a16"],["4b6580c1.f10c6","8343ee88.6811a"],["c576495c.2a52d8","eca7aaa7.d4c7e8"]]},{"id":"d4f21e42.19fb9","type":"inject","z":"5dd2ed34.6894bc","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"1","crontab":"","once":true,"onceDelay":"0.2","x":362,"y":825,"wires":[["f361a804.0ea4d"]]},{"id":"9f2359bf.354838","type":"ui_text","z":"5dd2ed34.6894bc","group":"44e5433c.f98cac","order":5,"width":0,"height":0,"name":"","label":"Ventilator Status: ","format":"{{msg.payload}}","layout":"row-right","x":742,"y":805,"wires":[]},{"id":"ecbb9f58.459318","type":"ui_slider","z":"5dd2ed34.6894bc","name":"","label":"ahTol slider","tooltip":"{{value}} %","group":"8eae17cc.67f588","order":1,"width":0,"height":0,"passthru":false,"outs":"all","topic":"","min":"5","max":"50","step":"5","x":240,"y":540,"wires":[["aaf9ce50.654c9"]]},{"id":"aaf9ce50.654c9","type":"function","z":"5dd2ed34.6894bc","name":"ahTol","func":"var ahTol = {};\n\n\nahTol.payload = msg.payload;\n\nflow.set(\"ahTol\", ahTol);\n\nreturn msg;","outputs":1,"noerr":0,"x":390,"y":540,"wires":[[]]},{"id":"967df6b6.66d01","type":"ui_text","z":"5dd2ed34.6894bc","group":"44e5433c.f98cac","order":2,"width":0,"height":0,"name":"","label":"Vandindhold Kælder (g/m3)","format":"{{msg.payload | number:1}}","layout":"row-spread","x":772,"y":725,"wires":[]},{"id":"f95cc6b1.beeed","type":"ui_text","z":"5dd2ed34.6894bc","group":"44e5433c.f98cac","order":4,"width":0,"height":0,"name":"","label":"Vandindhold Ude (g/m3)","format":"{{msg.payload | number:1}}","layout":"row-spread","x":762,"y":765,"wires":[]},{"id":"4b6580c1.f10c6","type":"ui_gauge","z":"5dd2ed34.6894bc","name":"","group":"44e5433c.f98cac","order":1,"width":"3","height":"3","gtype":"compass","title":"aH diff. (Ude-Kæl)","label":"g/m3","format":"{{value | number:1}}","min":"-10","max":"10","colors":["#00b500","#e6e600","#ca3838"],"seg1":"65","seg2":"70","x":742,"y":925,"wires":[]},{"id":"d7cbd3ee.50a16","type":"ui_text","z":"5dd2ed34.6894bc","group":"8eae17cc.67f588","order":3,"width":"3","height":"3","name":"","label":"Setpoint","format":"{{msg.payload | number:1}}","layout":"col-center","x":712,"y":885,"wires":[],"info":"__"},{"id":"8343ee88.6811a","type":"ui_chart","z":"5dd2ed34.6894bc","name":"","group":"44e5433c.f98cac","order":3,"width":"3","height":"3","label":"Forskel","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"bezier","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":"5","removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":932,"y":925,"wires":[[]]},{"id":"784a5652.4b54a8","type":"inject","z":"5dd2ed34.6894bc","name":"","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":true,"onceDelay":0.1,"x":230,"y":1020,"wires":[["2f51fa3f.e3658e","ee10749f.6f4c78"]]},{"id":"279da797.013538","type":"ui_text_input","z":"5dd2ed34.6894bc","name":"","label":"Dato","tooltip":"","group":"5bd990b3.dca3","order":1,"width":0,"height":0,"passthru":true,"mode":"text","delay":300,"topic":"","x":610,"y":1000,"wires":[[]]},{"id":"2f51fa3f.e3658e","type":"moment","z":"5dd2ed34.6894bc","name":"","topic":"","input":"","inputType":"msg","inTz":"Europe/Copenhagen","adjAmount":0,"adjType":"days","adjDir":"add","format":"DD/MM/Y","locale":"en_gb","output":"","outputType":"msg","outTz":"Europe/Copenhagen","x":440,"y":1000,"wires":[["279da797.013538"]]},{"id":"647de97b.5d0b7","type":"ui_text_input","z":"5dd2ed34.6894bc","name":"","label":"Tid","tooltip":"","group":"5bd990b3.dca3","order":2,"width":0,"height":0,"passthru":true,"mode":"text","delay":300,"topic":"","x":610,"y":1040,"wires":[[]]},{"id":"ee10749f.6f4c78","type":"moment","z":"5dd2ed34.6894bc","name":"","topic":"","input":"","inputType":"msg","inTz":"Europe/Copenhagen","adjAmount":0,"adjType":"days","adjDir":"add","format":"HH:mm:ss","locale":"en_gb","output":"","outputType":"msg","outTz":"Europe/Copenhagen","x":440,"y":1040,"wires":[["647de97b.5d0b7"]]},{"id":"4c9de6d7.98bc9","type":"ui_gauge","z":"5dd2ed34.6894bc","name":"","group":"8eae17cc.67f588","order":2,"width":"3","height":"3","gtype":"gage","title":"aH Tol","label":"%","format":"{{value | number:1}}","min":"0","max":"100","colors":["#53d6fd","#00a3d8","#006d8f"],"seg1":"65","seg2":"70","x":702,"y":845,"wires":[]},{"id":"eca7aaa7.d4c7e8","type":"ui_chart","z":"5dd2ed34.6894bc","name":"","group":"44e5433c.f98cac","order":6,"width":"6","height":"4","label":"Vandindhold (g/m3)","chartType":"line","legend":"true","xformat":"HH:mm:ss","interpolate":"bezier","nodata":"","dot":false,"ymin":"0","ymax":"20","removeOlder":"5","removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#ff2600","#3a88fe","#00fa00","#ff2600","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":1110,"y":480,"wires":[[]]},{"id":"c576495c.2a52d8","type":"ui_chart","z":"5dd2ed34.6894bc","name":"","group":"8eae17cc.67f588","order":4,"width":"6","height":"2","label":"On/Off","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"step","nodata":"","dot":false,"ymin":"0","ymax":"20","removeOlder":"5","removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#ff2600","#ff2600","#ff2600","#ff2600","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":1002,"y":805,"wires":[[]]},{"id":"f5869f70.a4834","type":"ui_chart","z":"5dd2ed34.6894bc","name":"","group":"1a5ecff2.92b44","order":3,"width":0,"height":0,"label":"Luftfugtighed Kælder","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"20","ymax":"100","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":1120,"y":400,"wires":[[]]},{"id":"d7586f4.5a02e1","type":"ui_chart","z":"5dd2ed34.6894bc","name":"","group":"b37cbe7b.05118","order":3,"width":0,"height":0,"label":"Luftfugtighed Ude","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"20","ymax":"100","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":1110,"y":440,"wires":[[]]},{"id":"b0c09932.02228","type":"inject","z":"5dd2ed34.6894bc","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":90,"y":540,"wires":[["ecbb9f58.459318"]]},{"id":"25b2494d.73122e","type":"netatmo-config-node","z":"","client_id”:”HIDDEN”,”client_secret”:”HIDDEN”,”username”:”HIDDEN”,”password”:”HIDDEN”},{“id":"1a5ecff2.92b44","type":"ui_group","z":"","name":"Kælder","tab":"c097c657.697cb8","order":2,"disp":true,"width":"6","collapse":false},{"id":"b37cbe7b.05118","type":"ui_group","z":"","name":"Ude","tab":"c097c657.697cb8","order":1,"disp":true,"width":"6","collapse":false},{"id":"44e5433c.f98cac","type":"ui_group","z":"","name":"Analyse","tab":"c097c657.697cb8","order":3,"disp":true,"width":"6","collapse":false},{"id":"8eae17cc.67f588","type":"ui_group","z":"","name":"Input","tab":"c097c657.697cb8","order":4,"disp":true,"width":"6","collapse":false},{"id":"5bd990b3.dca3","type":"ui_group","z":"","name":"Info","tab":"c097c657.697cb8","order":5,"disp":true,"width":"6","collapse":false},{"id":"c097c657.697cb8","type":"ui_tab","z":"","name":"Main","icon":"dashboard","disabled":false,"hidden":false}]

Please read How to share code or flow json and then EDIT your post and fix it so it can be imported.

Hi @Zenofund, thanks for your reply.
I did that now. Better?

Side question : what is the main purpose of this ventilator you are trying to automate?

I think you've missed the backticks on a BLANK line before and after your block of code.

Lol. If I cannot even figure out how to post here... aaargh.
The pupose of the vent is simple: i have a basement with a natural high humodity in sunmer time of 70’ish percent relative hum (Denmark).
The code will measure basement and outdoor relative humidity and temperature and calulate gram/m3 water contents in the air. If outdoor water contents are lower than inddoor, the vent should run and dehumidify the basement.

OK.
The timer component then. It controls the running time and turns off the vent. The humidity conditions still require vent to be running. Same goes to manual turn off. So in this situation the automatic "turn on" should be avoided somehow if I'm correct. How long this state last or what triggers the end of "must be off and can't be switched on by automatics" situation. It is not good practice to restrict manual control so manually turning to any state at any time should override every other logic.

Just go back and edit your original post - put three backticks on a line by themselves both before and after the code block and it will go into a single line window

Craig

OK just to summarise what you are trying to achieve

  1. A manual turn on mode - regardless of humidity levels etc - this will run indefinitely until turned off ?? or on a timed basis ? At the end of this manual cycle - does the system revert back to automatic control i.e. the high and low humidity settings will control on/off ?

  2. A manual off mode - no conditions can turn the system on untiil Manual mode is turned off - how does this happen to cease manual mode- timed condition, button on dash etc ?

  3. Full automatic mode - turn on at X humidity and Turn off at Y humidity

Are there any more cases for this ?

If it is this fairly suimple i would suggest you look at the DSM node - takes a bit of wrapping your head around but will let you setup a Finite State machine that sounds just rihgt for this application.

Craig

Wuhuuu backticks = tjeck

The idea is:
Regardless of what starts the vent, there should be a maximum runtime (30min for example) and a pause (2hr for example). These should be adjustable.

Hum condition is: absolute hum indoor < absolute outdoor * tolerance (%)

If the hum condition are ok AND the minimum pause is ok = start vent
If the runtime is over = turn off vent.
Any manual on/off should override

I have previously made something like this in arduino, and ended with a load of bool vars and a long if, else if... else if... statement. Thought it was rather unelegant and are wondering if there is some clever programming tricks that I have overlooked.

Yep check out the DSM node

It will take you a while to wrap your head around it - but i took a hybrid Arduino/Picaxe system that had horrible code with lots of exceptions and jumps//loops/delays and have slowly started moving ti to this model.

Craig

You will need to get all the stuff right in your head and sketch out the flow so you can see how it should run

So for instance your statement

Any Manual on/off should override

needs scoping - for instance this infers a Manual on stays on forever - whereas i think you would want a manual on that comes on for a timed period and then reverts back to automatic control (as an example)

Thanks a lot Craig. I'll definately check that out.
And, yeah, your totally right about the manual on.. should still be timed... :wink: