3 temp readings, need to choose 2 closest and avg. them

Hi,
I have three temp sensors with MQTT which are located outside of my house. One in East side, One in South and One in West. Currently using the total avg of these three to control the Air pump /HVAC. When it goes to under -5 °C it will shut down completely. Other wise it uses scaled response.
During summer it worked like a charm.
Now during winter, as sun is starting to heat with its rays (especially the West side of the house) the three measurements can actually vary quite a lot (-6 on East and West Side, but +7 on sun shine side) hence the total AVG goes quite much "wrong". I've been trying to find how could I differentiate the 2 values which ever of the three, are closest to each other and use only them and discard the 3rd one and the use AVG only from those two ?

Any suggestions ?

For clarity lets just call them TEMP1, TEMP2 and TEMP3. So sometimes TEMP1 and TEMP2 are the closest ones, sometimes TEMP1 and TEMP3, etc, really depending on the sun position.

I kind of fixed it by using timers (mimic the sun position) ecluding always one, but looking for more elegant way (and to educate me and my fellow node red's :slight_smile:

Thank you!

I would do this via function nodes to do the following:
1 node for each input that stores the incoming temp into 3 separate a flow or global context variables

Output from each of those function nodes flows into a 4th function node that pulls all 3 context variable values, identifies the closest 2 values and averages them, sending that as the output to the rest of your logic.

It would be possible to do all of the logic in 1 function node assuming the incoming msg allows you to differentiate which sensor the latest input came from.

What form do you have the three temperatures in? Since you are already taking the average does that mean you have them in one message?
In fact if you show us how you are taking the average then we will know where we are starting from.

Hi, this function should give you the average of the 2 closest values. or the average of all 3 if they are all the same value apart

[{"id":"dca3cca7.f1566","type":"inject","z":"8d8a515a.78af18","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":940,"wires":[["14e03211.a80f06"]]},{"id":"14e03211.a80f06","type":"change","z":"8d8a515a.78af18","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"[$ceil($random()*10 - 5),$ceil($random()*10 - 5),$ceil($random()*10 - 5)]","tot":"jsonata"},{"t":"set","p":"hold","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":170,"y":900,"wires":[["c9a21acf.bb676"]]},{"id":"c9a21acf.bb676","type":"function","z":"8d8a515a.78af18","name":"","func":"msg.payload= msg.payload.sort((a, b) => a - b);\nlet diff =  (msg.payload[1] - msg.payload[0]) - (msg.payload[2] - msg.payload[1]);\nlet sum =msg.payload.reduce((a,v)=> a+v);\nif(diff===0){\n    msg.payload = sum/3;\n}else{\n    msg.payload = (sum - msg.payload[(diff > 0) ? 0 : 2])/2;\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":310,"y":940,"wires":[["e6a040d1.7cd61"]]},{"id":"e6a040d1.7cd61","type":"debug","z":"8d8a515a.78af18","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"\"Av - \" & payload & \" Array - \" & hold","statusType":"jsonata","x":530,"y":900,"wires":[]}]
1 Like

Just a side question, how do you have the sensors placed. Just wondering if the one on the sunny side is in a container that will heat up when the sun is on it.

Wouldn't you just sort them low to high, take the middle one and then see which of the other two are closer to the middle value and use that for your average ?

Craig

Thank you E1cid,

Most elegant I have ever seen. Thank you very much !

Hi zenofmud,

Yes unfortunately the onewire sensor head is quite exposed as it come out from air vent and adding any mechanicl housing would make it a eye sore :slight_smile: At least to me, hell typically no one else notices these things but the person who built it. As said I did not want to fix this mechanically, more to learn how to fix it with code (and learn) :slight_smile:

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.