Calculate input from two sensor nodes, then trigger output

Very new to Node-RED, have some basics working (dashboard with graphs from sensors, switch for relays), but did a decent amount of searching and either cannot find or just cannot grasp how to do this.

I have 2 ESP8266s with some custom/generic MQTT code. First publishes temp/humidity to greenhouse/temperature and greenhouse/humidity. Second is relay control and subs to esp8266/relay1 and esp8266/relay2 (relay1 is a light, relay 2 is a fan).

I am getting sensor data just fine and can switch light and fan just fine. The sensors publish every 10 seconds.

What I need is to calculate a number based on temperature and humidity to decide if fan needs to run (and also based on time, but I believe I can insert LS Filter for this). Ideally would include some hysteresis but not picky right now. This is what I need to calculate:

Tc = (($temperature - 32) x 5/9) - 3
Sv = 610.78 x e^(Tc / (Tc + 237.3) x 17.2694
Vpd = Sv x (1 - $humidity/100)

Then if Vpd is < 0.8, activate esp8266/relay2 (this is where I'd want to use LS Filter to only run during certain hours, and also hysteresis to have a delay of maybe 10 minutes before activating relay since last time).

I know this is probably relatively simple for most, but the majority of my code is just tinkering to function then left alone, so even some other examples I could adapt from would be great.

If it helps anyway, my use case is this: I am what I call a technical greenhouse grower (even have an AA degree in greenhouse production lol), finally got a small but decent sized greenhouse at home for all my veggie starts for home and for sale/donation. I am trying to maintain Vapor Pressure Deficit or VPD that is based on humidity and temperature to give the optimal environment for plant transpiration at night when greenhouse is sealed. My VPD isn't terribly controllable during the day, but at night the VPD can be far too low (right now is calculated at 0.03) which means they will not be able to transpire and also the increased dew point will create condensation causing moisture on the leaves leading to fungal issues. And yes, VPD is also very commonly used in cannabis growers, relatively new within the last 7-8 years to other greenhouse growers, but given my small space it is even more important. Plus it's fun to see how well I can dial things in not having a "proper" production greenhouse like those I've worked in.

Seems to be missing a closing bracket on second line, so not sure if my function is totally correct.

but this may help
using JS Math - JavaScript | MDN

const Tc = ((msg.payload.temp - 32) * 5/9) - 3;
const Sv = 610.78 * Math.pow(Math.E, (Tc / (Tc + 237.3) * 17.2694));
msg.payload.Vpd = Sv * (1 - msg.payload.humidity/100);
return msg;

example flow

[{"id":"a68774557ec82d1f","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"payload.temp","v":"1","vt":"num"},{"p":"payload.humidity","v":"80","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{}","payloadType":"json","x":90,"y":4760,"wires":[["59d156a50794ae9f"]]},{"id":"59d156a50794ae9f","type":"function","z":"d1395164b4eec73e","name":"function 157","func":"const Tc = ((msg.payload.temp - 32) * 5/9) - 3\nconst Sv = 610.78 * Math.pow(Math.E, (Tc / (Tc + 237.3) * 17.2694))\nmsg.payload.Vpd = Sv * (1 - msg.payload.humidity/100)\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":270,"y":4760,"wires":[["37c60b9a751797c6"]]},{"id":"37c60b9a751797c6","type":"debug","z":"d1395164b4eec73e","name":"debug 2489","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":470,"y":4760,"wires":[]}]

p.s.
There is a hysteresis node in the library and you can also use the delay node to rate limit a flow.

This is wonderful, thank you so much! You were right on the missing paren, that was my mistake. I added some to round to a single decimal and verified using an online calculator, all is looking good for debug output using the injected values.

Right now I am rather lost in actually getting the data from my MQTT outputs. I believe I need to join/convert/both to be formatted correctly, and I have been trying different methods but I unfortunately don't quite understand it well enough yet.

If you could help that would be super great, this is what the output looks like running both MQTT outs into a debug:

5/7/2024, 11:30:59 AMnode: debug 2491
greenhouse/dht/temperature : msg.payload : number
65.84

5/7/2024, 11:30:59 AMnode: debug 2491
greenhouse/dht/humidity : msg.payload : number
28.9

Thanks again!

As a beginner i would first point you to presenting data and flows in the correct manner, which then makes it easier for other to help you.

Thereā€™s a great page in the docs (Working with messages : Node-RED) that will explain how to use the debug panel to find the right path/value to any data item.

Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.

BX00Cy7yHi

You can also set the debug nodes to output the complete message object, which allows you to copy all the data.

When you supply a example flow it is good to supply inject nodes with the example data. So instead of mqtt in nodes, supply inject nodes, as others will not have access to your mqtt server and the subscriptions.

How to import/export a flow

Example join

[{"id":"bca7d0bf807d5b83","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"greenhouse/dht/humidity","payload":"70","payloadType":"json","x":200,"y":4860,"wires":[["7f4ed2927b3ad1b9"]]},{"id":"7f4ed2927b3ad1b9","type":"change","z":"b779de97.b1b46","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"$split($$.topic, \"/\")[-1]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":420,"y":4900,"wires":[["ae9e0bc3580aca15"]]},{"id":"854f86d1e7f7d272","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"greenhouse/dht/temperature","payload":"20","payloadType":"json","x":210,"y":4960,"wires":[["7f4ed2927b3ad1b9"]]},{"id":"ae9e0bc3580aca15","type":"join","z":"b779de97.b1b46","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":590,"y":4900,"wires":[["e4ba2e114a0cc317"]]},{"id":"e4ba2e114a0cc317","type":"debug","z":"b779de97.b1b46","name":"debug 2490","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":630,"y":4960,"wires":[]}]

These two measurements are from the same esp? Why can't you program it to send both measurements in a single JSON format message? Then no need to join messages in Node-red

Thank you SO very much! Your example is working beautifully!

I realized in my debug node I did not have it capturing the full message, so I did not have all the objects/buttons available.

I will be sure to read through those docs you have linked, and having worked with your examples now it will help me learn further.

I also see now that my simplistic approach for sending the data is going to make extra work for handling it here.

This was a rather last minute project that I kind of rushed since I will only have my greenhouse "active" for another two weeks at most. I will be taking time to rebuild everything in a more proper way after that.

Thanks again, I very much appreciate the help!

1 Like

To be perfectly honest, I never really understood (or saw the need to learn) how to manage JSON data (I know, it is relatively simple), mostly because the majority of my MQTT projects were just reading a single sensor with mosquitto_sub or activating relays with mosquitto_pub either manually or via crontab.

And also my esp8266 code is really just a slightly modified tutorial for the simplest way possible. This particular case was a very quick 2am project to start getting data until I rebuild into a proper project (right now the esp8266 is literally hanging from a piece of kapton tape and dht11 just zip tied to a rail).

So yes, it very much could be and should be reprogrammed, and now that I am learning more I will be doing that in the near future!

Sounds like a disposable greenhouse setup. Tomatoes?

Well more temporary/seasonal, I have about 100 starts each of tomatoes, peppers, broccoli/cabbage/kale/brussels, squash/watermelon, so this is their home until we get past all chances of frost. I start in plug trays indoors, pot up to 3.5", then once well established they go to greenhouse.

I'm planning to leave it up for doing some hothouse tomatoes/peppers but working on designing a proper case for everything. Aside from this esp8266, there is another with a relay control (from a different project) that is just in a tupperware container lol. It's at least mounted on standoffs and all that, but I didn't have a 3d printer back then.

1 Like