Writing a NodeRed flow to determine when my pool will be at an acceptable temperature using the sun and maths
I'm one of the lucky ones to have a pool at my home. But I never know when it's actually hot enough for me to go in, and having the ability to know in advance would be wonderful, since I could plan my day more easily.
We put our pool on the south-east corner of our property (which means it get sunlight for the whole day) and has a "bubble cover" that help them heat up in the sun.
I already have temperature sensors in my pool, yes sensors one at the top and one at the bottom
You can see at 18h45 the pump turning on and mixing the water (which takes about
You can also see that the temps start rising around
9h30 in a pretty linear way. A bit of digging later, and this time correlates with the sun elevation going over
35deg, which is the angle at which it starts covering almost all the pool.
After verifying this theory by checking day by day that it actually matches (at least somewhat, I don't want something precise to the second, just to the half hour), I started to work on predicting the temp.
Since the temperature rise is pretty linear, I went with a very basic linear interpolation between two points.
This also means that as I'm not using a fancy Ai to determine the temp, I can't do it before I have an acceptable value for the first and second point which I randomly set at 10h30
11 of July 2022 where I live, the sun attained
35deg at approximatively
9h28 (± 5 min)
9h28, the top pool sensor reported a temperature of approximatively
10h30, the sensor reported a temperature of approximatively
The timestamp for
1657438080s and the timestamp for
Let's say I want the temperature at 16h30 (
1657452600) we can use the previous defined formula like this:
Let's check the results, according to the sensor, at
16h30 the temp was
28.49degC, neither a bad result nor a perfect one. A
.5degC deviation is a high, but this was approximatively one hour after it started to heat up, it can't be that precise.
Doing the calculation again using the temperature at
y2 results in a prediction of
28.3degC which I find acceptable for such a crude solution
As I wanted to keep things simple (says the man writing code to predict the pool temperature), I used node red, which is a remarkable tool for quickly manipulating data or a stream of data.
In the middle of building the flow, I thought that it might be a good idea to have a floating
y2. I decided to use the last value gathered by the sensor (with a limit of
17h00 to avoid issues with the pump). So, I went ahead and rewrote most of it.
First part is an
inject node that start at
10h00 and triggers every
17h00, that then feed through a
function node that sets some constants:
I then use the
template node to build the query and the
influxdb in node to retrieve the data
The query for the temperature is almost the same except for the
GROUP BY using
time(60s), you'll see later why this is "needed".
This query gives a result similar to this (
null meaning the sensor didn't have a value at the time):
I then immediately enter a
function node to get the time when the sun reached 35degThe code loops through all the points and if the elevation is greater than
35deg store it in the message object and return it.
I then need to join the two separates messages from the two queries into one. The simplest way to do it I found is to use a
join node configured to expect two messages and return one array as the payload, followed by a
function node to re-organize it
And this is why I used two different time groups in the query on array will be bigger than the other. It's very hacky, but works, I'm welcome to a suggestion (using a topic as the key pop's in my mind)
Originally, I planned to smooth out the temperature to get a more accurate reading, that proved wildly ineffective and decreased the accuracy by approximatively
3degC, here is the code for the node anyway (it's a basic low-pass/smoothing function):
Next, the data goes to another
function node to extract the temp when the sun is at
35deg and the temp either now or at
17h00:It's very similar to the first function, it loops through all points and when it meets the condition, stores it in the message object and break out of the loop.
To get the last point between
09h00, I reverse the data and added a simple condition to check the hours (this means that, right now, it will get the value around
17h59, not an issue though).
Now that we have our constants for the linear interpolation, we can use another
function node, to create the values:First, we declare some constants like the
step time for the interpolation. Next, we use the function defined in the last part and create the dataset, assign it to the message object (along with the constants) and return it.
The next step is to get when the top of the pool will be at
28.25degC. To accomplish that, I use yet another
function node and use the same code as I used to get the temps at a specific time, the only difference being that I search for the time instead of temperature. I also added a little margin to make sure I catch a value.
NB: I cloud have done the proper thing here and calculate an equation that take a temperature and return a timestamp, but it's 3am 🛏️ and don't really need it in this instance.
The last step is visualization, the first thing that happens is that the message goes into a
function node that will round all the values to an acceptable decimal point (2 for the values and 6 for the interpolation parameters)
Then, it goes into multiple
template nodes that then goes into multiple
UI nodes, a
debug node and an
homeassistant sensor node:
And that gives me a nice NodeRed dashboard:
And you can see that (at least when I wrote this article) the prediction pretty much spot on. The ha sensor does his job and can be visualized in the dashboard:Don't mind the graph the values are a bit messed up because I put the wrong value in the state during testing and didn't bother clearing the database.
This was done as an experiment and for fun when I noticed that the temperature curve was somewhat linear, not as an actual statistical analysis that I would actually rely on. I'm not a maths head either, there are probably better ways to do this.
To get the actual temperature of the pool, I would need to do some more maths to average the top and bottom sensor, I, however, do no care 😅.
Things I learned:
If you want the flow, email me (see my portfolio), I'll send it to you. If you would like to chat about it or other projects, please join my discord (https://discord.com/invite/z8bwtdE) or directly comment below 😄
Want to chat about this article? Just post a message down here. Chat is powered by giscus and all discussions can be found here: TheStaticTurtle/blog-comments