Almost two months ago, I wrote a blog post outlining how I built a Machine Learning model for ASHPs. Powered by the data from OpenEnergyMonitor, it was quite basic. It used the Target Temperature and the Outdoor temperature to predicate energy consumption.

It was my first go at Machine Learning (ML), so I wasn’t expecting much, but it worked.

Room Temp is useless by itself!

However, as I continued work on my Heat Pump Matter simulator, I realised my model was all wrong!

I should have known better really, but I was busy making it work, rather than making it right. The amount of electricity required by a heat pump is driven by the amount of heat it needs to output. Room Temperature does, in a way, drive the heat required, but it’s not the whole story.

For goodness sake, different rooms can have different temperature requirements 😂

Let’s imagine we have two buildings.

One is a two up, two down. The other is a stately home with 50 rooms. The people living in these hours both want the room temperature to be 21°C. Which is going to be need more heat? 🤣

If I used my current model on both of these buildings, it would give me the same output for both.

21°C inside temperature with a -5°C outside temperature would always yield the same electricity value in my current model.

Flow temp?

My initial thought was to use the flow temperature, that’s the heat of the water coming out, instead.

If the flow temperature is much higher than the air temperature, the heat pump has to work harder.

This is because the system works by putting heat into the water coming back into the heat pump. This is the return. Flow goes out, return comes in. There will be a temperature difference between these as heat is taken out of the water by the radiators.

The heat pump then extracts heat from the air and puts it into the return water. This lifts the temperature back up to the desired flow temperature. And the cycle repeats.

The higher the flow temperature, the hotter the heat pump has to run so it can transfer the heat. The hotter the heat pump is running, the more electricity is needed.

It’s easier for a heat pump to warm water from 30°C (return) to 35°C (flow) than it is from 40°C to 45°C. Even though the same amount of energy is needed (5°C rise), one side needs to be hotter for the transfer to happen. I can’t heat water to 45°C if my source is only at 40°C. A lower flow temperature means a lower heat pump temperature. A lower heat pump temperature means less electricity.

But, like room temperature, it doesn’t tell the whole story.

Technically, I can heat both the small house and the mansion with the same flow temperature. Flow temperature itself only comes into play when I’m looking at radiators. Radiators, like the heat pump, need to be hotter than the room so they can transfer heat. The cooler the radiator, the less heat is transfers.

But size matters. The larger the radiators, the most heat it can transfer. If you have bigger radiators, you can use a lower flow temperature. I’m delivering the same amount of heat, just at a lower temperature.

So, if flow temp is no good by itself, what’s the missing variable?

Mass Flow Rate

When it comes to the movement of heat, there are two variables to consider.

In hydronics, there is this concept of Mass Flow Rate. It sounds complex, but it’s all about the mass of water being moved around. A “lump” of water at a certain temperature holds a certain amount of heat. As that lump of water moves through a radiator, it gives up its heat. The more heat we need to deliver, the more water we need to move in the same time period.

Let’s look at our two up, two down house. Let’s imagine it needs 2kW of heat to keep it at 21°C when it’s -5 outside. The formula for Mass Flow Rate is this

I hate formula too. This says that the mass (m) is equal to the amount of heat (Q) divided by heat the water holds.

For our little house, using the classic ΔT of 5°C, this tells us we need to move about 0.1 kg of water per second. Thankfully, one kg of water is the same as one litre of water, so we’re moving 0.1 litres of water per second.

For our mansion, let’s say we need 10kW of heat. That’s basically 0.5 litres of water per second.

The key variable here is the flow rate.

So what do I really need?

Going back the OpenEnergyMonitor data, I identified more variables that seem relevant:

  • heatpump_flowrate
  • heatpump_flowT
  • heatpump_outsideT

Would these give me better predictive results?

If I know my home needs a flow temp of 45°C to deliver 7kW, I can work backwards to get flow rate. I then feed these values into to get the electricity demand.

What’s interesting is that the OpenEnergyMonitor data also provides heatpump_heat, which is how much heat is being delivered. If I know I need 7kW, could I use that with the outside temp to get the electricity demand?

Again, I feel like the heat measurement isn’t enough. I can deliver 7kW of heat at a flow of 35°C or 50°C (depends on my radiators). In the case of 50°C, the heat pump is running hotter in order lift the temperature up.

Using the Mass Flow Rate, we specify both the flow rate. To account for the work the heat pump is doing, we use the flow temperature and the outdoor temperature.

These are our variables. Or at the very least the ones we’ll try next.

Trying it out!

I started by adjusting the training set to pull out the new variables.

elec = time_series_data['heatpump_elec'][i]
flowT = time_series_data['heatpump_flowT'][i]
flowRate = time_series_data['heatpump_flowrate'][i]
outsideT = time_series_data['heatpump_outsideT'][i]

The training code then changed a little to use these variables

X = df[['FlowTemp', 'FlowRate', 'OutsideTemp']]
y = df['Input']

I needed something to compare my output with, so I hopped onto heatpumpmonitor.org and picked the first 5kW heat pump I saw and opened a day at random.

Looking between 10am and 12pm, the flow temp was 25°C, flow rate was 14°C and outdoor temp was 13°C.

My model spat out 135W.

Open Energy Monitor showed 355W.

Yikes. Not even close.

Cleaning up the data

I’m no data scientist, this is all new to me, so figuring out the next step was difficult. I decided to start with improving the data.

In the image above, you can see periods when the flow rate was 0 (between 3am and 8am)

I eliminated all rows from the training data where the flow rate was 0.

The result was even worse: 123W 🤣🤣

I looked over the data and spotted something. The flowrate values in the CSV were *massive*. Values like 540 and 280. That certainly wasn’t litres per minutes, unless these houses were build to house jumbo jets. I checked the feed information and saw my mistake.

The unit was m³/h, but the values were bonkers. 540 m³ of water is like 540,000 litres. To move that in an hour needs a flow rate of 9000 litres/min. Which is absolutely wrong.

After some help from one of the co-creators of OpenEnergyMonitor, I discovered that the unit isn’t always m³/h. Sometimes it’s l/min.

I made a few more tweaks. I also used the start_time and end_time from the feeds to ensure I had the most data available. This produced much better flow rate values, ranging from 5 to 15. I also dropped any flow rates below 5.

I picked another system

This was had a pretty consistent cycle. It showed consumption of 430W. My model predicted 580W.

A must better result, but still 30% out.

Of course, I wasn’t accounting for the higher consumption during the compressor starts. The flow and return have their widest gap here as the system heats up.

This peaked at 720W before dropping down to 430W.

If I try and average that out, the figure is above to 500W, which improves my prediction value.

Next Steps

I’ve learned a lot more about the quality of training sets during this tinkering session. My prediction value seems to be much better. I am still no data scientist, and this digging is more for my own amusement than anything serious.

What I need to do next is look at how I validate my model’s predictions. I probably need to take some of the training data and use that as test data?

Would my prediction bear out if averaged over a whole day, for example?

What other parameters come into play that I need to account for?

That’s a job for another time!

All my code is available at https://github.com/tomasmcguinness/ml-python-heatpump-model

Support

If you find my blog posts useful or informative, you can always say thank you by buying me a coffee. Your support is appreciated!

Buy Me a Coffee at ko-fi.com

Be sure to check out my YouTube channel.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.