Heat pump experiment review after two years

Thanks @MyForest for all of your help and suggestions above, I will get back to you on this shortly. It’s been a really interesting heat pump install to try and understand and work out what’s going wrong. Will share more about it soon hopefully.

1 Like

@MyForest

Hi myforest I have installed an ecodan 6kw heatpump and also an emonpi to monitor its power usage. I have the basic energy monitoring on the ecodan which comes with a flow meter which is nice as it can give approx cop. However looking at the MELCloud app the power usage compared to my emonpi can be very close some days and then off by 20% or so on other days. From your digging around inside the MELCloud api have you seen anything in the way the ecodan measures power to suggest why there would be such a difference. Of course it could be the emonpi that’s wrong I guess.

Cheers

Hi @Gavin_Armstrong

I’m a bit torn on this.

My gut feeling is that the MELCloud stuff can’t be right because it reports numbers that we all find hard to believe. For example, it reports energy is being generated when it’s turning off. It could be right because warm water is being pumped around.

So I’ve decided to take their readings with a pinch of salt. It’s nice to have an mostly gives something I can use to guide what I’m doing. I wouldn’t bet my house on the numbers though.

However, I also correlated what was being reported by MELCloud and absorbed into EmonCMS by my scripts with what electricity the meter says has been consumed. It seemed close enough that I decided MELCloud was good enough.

I wouldn’t be surprised to see a 20% variation on occasion, but that it’s right most of the time.

Finally got round to setting up the script to read from melcloud, I’ve been getting really good data from the emonPi on this customers heat pump, it will be interesting now to see how melcloud compares:

import aiohttp
import asyncio
import pymelcloud
import requests
import json
import time
import math

from inspect import getmembers
from pprint import pprint

async def main():

    async with aiohttp.ClientSession() as session:
        # call the login method with the session
        token = await pymelcloud.login("EMAIL ADDRESS", "PASSWORD", session=session)

        # lookup the device
        devices = await pymelcloud.get_devices(token, session=session)
        device = devices[pymelcloud.DEVICE_TYPE_ATW][0]

        last_update = 0

        while True:
            if math.floor(time.time())%60==0:
                
                # perform logic on the device
                await device.update()

                props = [
                  'FlowTemperature',
                  'ReturnTemperature',
                  'CurrentEnergyConsumed',
                  'CurrentEnergyProduced',
                  'DailyHeatingEnergyConsumed',
                  'DailyHeatingEnergyProduced',
                  'DailyHotWaterEnergyConsumed',
                  'DailyHotWaterEnergyProduced',
                  'DefrostMode',
                  'DemandPercentage',
                  'HeatPumpFrequency',
                  'OutdoorTemperature',
                  'TankWaterTemperature'
                ]
                
                data = {}
                for key in props:
                  data[key] = device._device_conf['Device'][key]
                
                print (data)
                
                reply = requests.get("https://emoncms.org/input/post", {'apikey':'APIKEY', 'node':'melcloud', 'data': json.dumps(data)}, timeout=60)
                print (reply.text)
                
                time.sleep(1.1)
                
            time.sleep(0.1)
            
        await session.close()

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

The goal this winter is to hopefully improve their COP by quite a bit through better balancing and system control and write up the results as a case study next year.

1 Like

A little comparison of the data so far, here’s the flow and return temperatures from melcloud vs the emonpi, looks great!

Melcloud heat pump frequency vs emonpi CT sensor:

Melcloud heat pump energy consumed vs emonpi CT sensor, resolution is a bit poor but maybe we can use this with the right scaling factor…

Melcloud energy consumed and produced x1130 matches emonpi electric consumption: suggests COP around 4.1… great…

Daily heating energy and daily hot water energy vs emonpi CT sensor, not sure what’s going on here…

Simulated heat output using carnot COP equation suggests a COP that’s a bit lower at 3.54…

Will be interesting to see how these results compare over time. I think I might piggy back onto the Sika VFS flow sensor used by the EcoDan and try and read the flow rate into the emonPi with a simple analog voltage input…

2 Likes

That looks like a metric that’s their view of the whole day. I don’t use that.

That is a great idea, it will be interesting to see that. You’re in a good position to see if the MELCloud stuff is working as expected. It’s notable that you have finer-grain data from emonpi. One of the questions people keep asking me is “what granularity do we need?”. For example, SMETS is half-hourly - is that good enough to understand usage or do you need each minute, or every six seconds? Specifically for me, with solar input varying by the second I need local control by the second, but for modelling purposes it may be that half-hourly is sufficient.

As you’ve probably gathered, I’m trying to do mine without interfering with the device at all. I’m trying to make sure I don’t mess up my RHI rebate.

Hello @MyForest . This looks really interesting work. I will need to rev-up my brain in order to digest it all. I am not the fastest at understanding things.
I would love to get my old 5kW Ecodan controlled better, but my FTC3 is far too old for MelCloud sadly.

Hi @johncantor,

Thanks for the kind words.

If you think it would help I’m happy to chat to you directly or even show you some of the experiments. Just let me know when would suit you. I’m up in Yorkshire and I believe you are not, so we may end up doing it virtually, but I can drive to places if that helps. It’s the least I can do for you considering the efforts you have put in over the years (including your book sat next to my arm right now which I show to friends who ask about these things).

I don’t think I’ll be able to get MELCloud on your FTC3 though :slight_smile:

David

Hi. I’m a newbie here, but I know some python and other stuff. Great stuff so far and thanks for all the info and code.

The following line looks like it would be sending the data to emoncms.org — could someone tell me what sort of line I should be using to feed the data directly into my local emoncms on a RPi running emonsd-21Jul21, please? Or even which bit of TFM I should R for such info.

Thanks.

Hi @mjr,

I do this, which is practically the same as Trystan’s example, but if you are familiar with Python you’ll see me doing some other things which might be interesting to you.

encoded_data = (
        "time=" + str(int(readingDateTimeUTC.timestamp())) + "&node=ecodan&apikey=some_secret_string&data=" + json.dumps(toPost, separators=(",", ":"))
    )

headers = {"Content-Type": "application/x-www-form-urlencoded; charset=utf-8", "User-Agent": "ecodan/post_to_emon.py"}

encoded_data = encoded_data.encode("utf-8")

http = urllib3.PoolManager()

r = http.request(
    "POST", "https://my-server/input/post", headers=headers, body=encoded_data, timeout=urllib3.Timeout(connect=1.0, read=2.0), retries=False
)

result = r.data.decode("utf-8")
if result != "ok":
    pprint.pprint(result)
    raise Exception("Unable to post")

I tend to use requests rather than urllib but obviously the day I wrote this I decided to use urllib. Of course string concatenation is very bad too so I wouldn’t propose anyone does that.

David

1 Like

Thanks for that. So I think I just POST to /input/post on the pi running emonsd. Maybe it will become obvious to me what to do after that! Most of this seems to become obvious once I start but I feel like I’m failing to find developer/customisation docs in the Guide or the pydoc or somehere.

And just as an aside @MyForest, your heat pump experiments were a big encouragement for us to go for an ecodan (and gave some hints on how to configure it more efficiently than the installer did even with the stock FTC controller — they basically set it on room temperature apparently without a weather compensation curve or using the outdoor sensor at all), as well as motivating me to finally dig out the RPi and connect it up again, to see summary detail on what the heating is doing a bit more easily than risking repetitive strain injury tap-tap-tapping the melcloud app.

I’ve also plans for Total World Domination using smart radiator valves and so on, but one step at a time and no risking the RHI repayments!

1 Like

Hi @mjr

You want to go to /input/api and you’ll see all the help you can dream of.

I’m assuming you saw this:

https://community.openenergymonitor.org/t/improve-efficiency-user-comfort-with-trvs-and-flow-return-mode-on-air-source-heat-pump/

Particularly, the TRVs are at something like 23 °C at the moment but my algorithm keeps turning off the heat pump before the air temperature gets close to that. The air temp is actually about 20 °C. I’ve been scratching my head trying to work out what aspect of the system is keeping the occupants comfortable without any room temperature interaction but across a wide range of external temperatures. At the moment I can’t explain why my system is working so well in this respect.

1 Like

Yes, I’ve got that, but I mean more like what’s the recommended location and launch/relaunch method for my data collection scripts for the least painful updates in future? Are there ways that the usual upgrades are unlikely to break?

Yes, I saw that post. I think you’re correct to view Thermostatic Radiator Valves as basically an upper limit on what that room will take from the heating loop. That’s my first task for a controllable TRV, to turn down heating in a room at times when no-one is in it, but ideally with some pushbutton to start heating it as soon as we know someone wants it, even if we’re not home, before they start their journey (in part because our low-temperature radiators don’t heat rooms quickly and I don’t want to use the old heater if we can avoid it). Expect some questions from me on a post about smart/remote TRVs some time soon!

I also don’t understand why some TRVs say they won’t work with heat pumps, unless maybe some don’t work well with low-temperature radiators and need the old 60-70 degree heating loops.

Why is your system working so well? As I understand it, your control program does “feels like” weather compensation with some extra logic to reduce cycling and avoid pumping water when it’s not being heated, so I think you’ve effectively implemented a curve that matches your heat loss and desired target temperature. And one of your tweaks is to stop heating when the radiators aren’t losing enough heat, which I think would happen when all rooms are close to that curve’s target value, effectively using the heating loop as a whole-house thermostat! If one room is disproportionately cold, I think its TRV would be more open so it would take heated water more quickly than the others and lose enough heat to keep the pump running, and eventually bring that room back up and balance the system again, allowing the return temperature to get close to the flow and stop.

How good is your program at recovering from events like someone foolish switching the heating off in error for a few hours in winter? Using the Mitsubishi controller’s curve settings, I have at least once lost control of the house temperature so it wasn’t coming back on its own any time soon. I brute-forced a recovery by switching to flow temperature mode and setting a fairly high flow temperature until analogue thermometers around the house all read OK. Then I set a new curve using the learning (new values and a bigger bend to account for how exposed to the wind we are), switched back to curve mode, rinsed and repeated.

I suspect your control logic would do better than Mitsubishi’s because it could factor in other sensors and take more extreme actions. The Mitsubishi’s curve mode seems to be reacting to the outdoor sensor alone, pays no attention to the room thermometer and does not react much to the flow-return difference: as far as I can tell, it stops heating if the flow-return difference gets small, but it still runs the pump most of the time and it never reacts to a large flow-return gap by increasing the flow temperature temporarily.

I hope that you will permit me to slightly drift into two other quirks that I found while experimenting with our ecodan about which I’d like to ask for other experiences:

  1. It seems that our ecodan always heats water up to the set temperature every time hot water comes out of a “prohibit” timer phase, even if the tank sensor temperature is within than the allowed drop. Is this normal? Do others? I currently exploit this to heat most of our water with cheaper overnight electricity (by having a prohibit ending at something like 4am) but it is generally a bit annoying because there are times of the day/week when I’d like not to heat water unless it’s really really needed, without always reheating the tank at the end of such a period. I guess I could use pymelcloud to turn the tank set temperature down and up on a schedule but that may be a bad idea for some reason I’m not thinking of, or, even more intrusively, have no schedule and use pymelcloud to press the virtual “Heat Now” button if a mix of time and tank temperature sensor conditions are met.

  2. Does the Mitsubishi’s room thermostat mode heat the radiators to higher flow temperatures but more intermittently, for shorter times in total? Is that how it is expected to work? That seemed to combine with our windswept location to deliver a poor CoP (closer to 3 than 4) and higher bills in early November (and 6-9°C out so not that cold) and motivated me to start reading and then experimenting.

Ah, I see. I’m using this all in Docker so I just keep my scripts outside and they don’t get impacted by updates. Sorry, that probably isn’t helpful.

I’ve got location data from our EV in realtime. Maybe you could just see if the car is moving, predict how long it’ll take to get home and how long the heating will take and just turn it on automatically. That’s assuming you don’t stop off on the way home to take your mum some nice flowers.

Yep, even radbot says it in their FAQ. I ran out of time to ask why.

You might be on to something there. I hadn’t thought of it that way, but that is what I’m doing.

That’s been happening for the last few weeks. We have an intermittent power fault unrelated to the ASHP. When the power is restored the dumb regular thermostat receiver that we don’t even use defaults to “off” so the house starts getting colder. Sometimes it’ll be hours later before we realise and manually kick the manual thermostat to unblock things. The dumb thermostat is set to 26 C so it should always be “on” but it’s waiting for a state transition so just sits around shrugging it’s shoulders whilst everyone else is working to do a good job.

So basically it doesn’t get cold from that type of event because the house is already warm.

We do have a daily occurrence of what you describe though because we don’t heat the house overnight (we’re all asleep under duvets). So in the morning it has to get going. Here’s a typical long run (in this case with a weird gap) that we see in the morning. You can see it takes an hour to get up to temp so just trundles along until it’s been at the max temp for a few minutes.

Yep, that would be frustrating.

You can see my algorithm is responding to a small deltaT by lifting the target temp so the deltaT gets bigger again (for a while at least).

So my strategy of walking up the temperature means it’s running at very low temps for quite a while to start with, such as that 28 C for 10 mins at the beginning. That’s similar to what @johncantor and @TrystanLea see with their FTC2 slowly lifting the flow temp rather than my FTC5 and John’s FTC6 (and presumably yours) which are ramping up the flow temp really quickly.

I very much do the last thing. Mine is on prohibit the whole time and my algorithm decides when to poke the ForcedHotWaterMode button.

To do your “overnight” thing I have this line of code to bump up the desired temp so I’m using it as a heat battery:

if OctopusGo.powerWillBeCheapForNextFifteenMinutes(calculationMoment, deviceInfos):
    desiredWaterTemperature = 52

and the other code that looks at the discrepancy might decide that’s reason enough to jump in and turn on the heat pump, or maybe not, especially if it’s already pretty warm.

1 Like

I’m afraid I didn’t run it long enough to be sure. It kept cycling so much and running the circulating pump so long that I took over in 2019-12 and haven’t looked back. I did experiment with the different modes but nothing made it behave well.

Just for your reference, here’s how ours behaved in 2021-11 before it went a bit haywire when I lost control. It’s about 10 heating runs per day.

Well here’s the worst it’s been since we got the heat pump @mjr. Something else keeps taking the power down and we ended up turning things off for hours on the 8th when it was already cold. We were actually unhappy for the first time.

This graph also shows how the temperature normally drops a degree or two each night when the heat pump is shut down.

I’ve zoomed in on the evening of the 8th after we got things running smoothly again.

So it looks to me like your system raises temperature by at most 1 degree in 45 minutes. Would you be willing and able to plot energy consumption and production over that zoomed in bit? I’m wondering how hard it was driving the heat pump to do that or if there is scope for a “quick warm-up” process to do more.

Here you go @mjr

Your query is a good example of why I built my app.

You’ll have to ignore the spikes on the hour which are a hiccup due to this MELCloud fun I’m having.

Normally my flow tops out at about 40 °C but you can see I was playing with it to “boost” it as you say (by re-compiling my Docker container :slight_smile: )

This is the first time I’ve felt the need to boost it. I could put something in my algorithm that looks at the room temps to auto-boost it I suppose. Our house doesn’t usually get cold so it’s not been something I was interested in.

Thanks. Apart from about 2130, it looks like your 14kW unit still has some capacity to spare.

I’ve been thinking more about weather compensation curves and quick warm-up and occupant tolerance for temperature fluctuations. In one way, weather compensation is very clever, proactively changing the heat output in response to external temperature change before it causes heat loss. In another way, it does the wrong thing, working the heatpump harder when its performance gets worse due to the falling temperature. I wonder whether it might be a good idea to increase the radiator temperature on a mild afternoon, putting more heat into the house when the heatpump CoP is better and letting the temperature fall slightly as it gets colder outside… or whether the occupants would notice that, feel cold and boost the heating anyway.

But because I cannot see how to remote control the +/- curve adjustment from melcloud, this will remain as idle wondering for me until I take the plunge and let the Pi set the flow temperature, and I’ve an LCD display and some buttons I want to get working before that!