Help needed with power saver flow for cooler/freezer with one compressor?

Hello!

We are looking for a flow for a cooler-freezer on an off-grid site.
It is basically a thermostat and power saver flow that should not allow the freezer to go above -15°COR the cooler to go above 6°C during the night and is typically inactive during the day but there is only one compressor to switch on and off.
It controls a Shelly relay (I have that standard part working) that should allow either 6°C cooler or -15 °C freezer.
Below is my work in progress but I only get to selecting the lowest value from two sensors, but as
freezer and cooler have different target values I am unable to figure out how to do this.Any help is much appreciated!

[{"id":"47e08a034fd04e7a","type":"change","z":"46a0c2550c075890","name":"choose lower value","rules":[{"t":"set","p":"payload","pt":"msg","to":"$min([$flowContext(\"temp1\"), $flowContext(\"temp2\")])\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":810,"y":180,"wires":[[]]},{"id":"15c22ab6c768dd19","type":"change","z":"46a0c2550c075890","name":"store temp1","rules":[{"t":"set","p":"temp1","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":160,"wires":[["47e08a034fd04e7a"]]},{"id":"2f7595bd83cfe6e6","type":"change","z":"46a0c2550c075890","name":"store temp2","rules":[{"t":"set","p":"temp2","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":200,"wires":[["47e08a034fd04e7a"]]},{"id":"5d84c3fac75402e0","type":"inject","z":"46a0c2550c075890","name":"temp source 2","repeat":"","crontab":"","once":false,"onceDelay":"1.5","topic":"","payload":"12","payloadType":"num","x":190,"y":200,"wires":[["2f7595bd83cfe6e6"]]},{"id":"bbc703fdf4f0e2f6","type":"inject","z":"46a0c2550c075890","name":"","repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":100,"wires":[["45d6c3270d2cb879"]]},{"id":"45d6c3270d2cb879","type":"change","z":"46a0c2550c075890","name":"set to high","rules":[{"t":"set","p":"temp1","pt":"flow","to":"999","tot":"num"},{"t":"set","p":"temp2","pt":"flow","to":"999","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":120,"wires":[[]]},{"id":"547fede413fdded0","type":"inject","z":"46a0c2550c075890","name":"temp source 1","props":[{"p":"payload","v":"10","vt":"num"},{"p":"topic","v":"","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"1","topic":"","payload":"10","payloadType":"num","x":190,"y":160,"wires":[["15c22ab6c768dd19"]]}]

If I understand what you are trying to say correctly IF the Cooler OR the Freezer are MORE THAN either Setpoint, the Compressor should be on. Are there temperatures to which the Cooler or the Freezer should be cooled to, irrespective of the other ones temperature (Dead Band/Hystresis)?

(I am not strong with JSON, but someone will be along that is.)

Thanks @mudwalker

You are correct in all your assumptions.
During daytime when there is PV, the freezer goes to maximum freeze, around -25°C
and the cooler to around +2-4°C. Then at night an automation switches to this "power-save mode"
that allows the unit set point temperatures to slowly rise to these other respective set points but not beyond them. The freezer is always full, as we add saltwater in containers to store the cold during PV hours and then rise very slowly during night. I hope I am being clear.

So you want to cool only as far as the Daytime Values, not others?

Perhaps I can be clearer:

  • During the day, the built-in thermostat in the fridge/freezer is in use, set to as high as possible without damaging the food to also store as much cooling as possible while PV is available.

  • During the night we switch to a node red flow controlling a shelly relay and two separate tempsensors for the fridge and freezer parts.
    The shelly relay cuts the power until any of the two spare set points for the fridge and freezer are reached, and then switches on when either of the two set points are reached.
    (This is the part that I am unable to figure out and would appreciate a flow example for.)

When this is in use, typically this means very little or no power usage at all during the night.

Assuming that you can distinguish the input sensor by msg.topic, does a simple function like this work?
It will send "OFF" whenever a temperature reading arrives, unless one or other temperature reading exceeds it's threshold value, when it will send "ON"

const coolertopic = "cooler"
const freezertopic = "freezer"

const coolermax = 6
const freezermax = -15

let output = "OFF"
if (msg.topic == coolertopic && msg.payload > coolermax) {
    output = "ON"
}
else if (msg.topic == freezertopic && msg.payload > freezermax) {
    output = "ON"
}
msg.payload = output

return msg;

I would probably add a when gate node (part of the latest cronplus) to only allow messages through during the nighttime, perhaps also a filter node to only pass changed payloads.

Thank you! @jbudd
Yes, there are separate temp payloads from the shelly addon.
Is the code you sent for a function node? Is it intended as a complete thermostat flow?
Your concept seems to be correct to me and I will have a look at this and try it asap.

Yes a function node.

I used a function rather than the basic nodes because I assume that a sensor message contains either cooler or freezer temp, not both. You could store them in context (as I think you do) and compare, I just handle each message as it arrives.

I do not think it's a complete solution.
For example you might need to build in an alarm in case one or other sensor stops sending.

Understood. It seems like a very good starting point.
I would like to replace my old thermostat code if possible as it is built for a Homekit thermostat and we no longer use HK. But one step at a time :wink:

Won't that give alternate OFF and ON when the value is between the two thresholds?

I think maybe it needs a Join node in manual mode to merge the two temperatures into one message before doing the test.

Yes of course that's right. If the cooler is too warm but the freezer is not, it will alternately send ON and OFF. Doh.

It should only send OFF if neither sensor reading is above it's threshold.

So the OP needs to store the readings for comparison, either using context or a join node.

Here is a revised flow

[{"id":"960d854436046fc3","type":"inject","z":"c45e985e77331d2b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"cooler","payload":"4","payloadType":"num","x":190,"y":100,"wires":[["2b3badbd3795d8ba"]]},{"id":"ccae393cb63d130a","type":"inject","z":"c45e985e77331d2b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"cooler","payload":"8","payloadType":"num","x":190,"y":140,"wires":[["2b3badbd3795d8ba"]]},{"id":"61cedd0ab23f1adc","type":"inject","z":"c45e985e77331d2b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"freezer","payload":"-20","payloadType":"num","x":200,"y":220,"wires":[["2b3badbd3795d8ba"]]},{"id":"3eddc4a68c6bbe83","type":"inject","z":"c45e985e77331d2b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"freezer","payload":"-10","payloadType":"num","x":200,"y":260,"wires":[["2b3badbd3795d8ba"]]},{"id":"2b3badbd3795d8ba","type":"join","z":"c45e985e77331d2b","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","useparts":false,"accumulate":true,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":370,"y":160,"wires":[["0074ef55952bf8d8"]]},{"id":"de896d8001943a3a","type":"debug","z":"c45e985e77331d2b","name":"debug 85","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":680,"y":160,"wires":[]},{"id":"0074ef55952bf8d8","type":"function","z":"c45e985e77331d2b","name":"Compare","func":"const coolermax = 6\nconst freezermax = -15\n\nif (msg.payload.cooler > coolermax || msg.payload.freezer > freezermax) {\n    msg.payload = \"ON\"\n}\nelse {\n    msg.payload = \"OFF\"\n}\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":160,"wires":[["de896d8001943a3a"]]}]

I think I shied away from a join node initially because it does not send any message until it has received both - so if one sensor stops working, so does the flow.
Fairly simple to code a timeout alert for each sensor though.