Improve efficiency: Turn the heat pump off

As we all know, the most efficient way to run a heat pump is to keep it running all the time.

However, I’d like to propose an alternative. I think there’s a case for turning them off.

Here’s 2019-10-26 - the average temp was 9 Celsius. We can see in the evening the pumps we on all the time and my records show the system was flipping between heating and anti-freeze.

This is a good example of why I split space heating and hot water in my efficiency analysis. The hot water usage is sporadic and dents the CoP in a way that distracts from an experiment like this. We can see space heating has a CoP of 2.58.

Contrast this with 2020-02-10 that also averaged 9 Celsius, but using an algorithm that turns off the heat pump off every so often. We can see it’s still £2.50 to do space heating but the CoP is 3.32. We got an extra 13kWh of space heating for free.

The obvious retort is that the residents will get cold when it’s off. However that’s a matter of perspective. I’ve surveyed them and they seem completely happy - they can’t tell the difference.

The over-sized radiators (cheap Stelrad K2) are acting as a heat store and gently releasing heat during the down time. Notice how we turn it back on when the “return” temperature of the heat pump is about 26 Celsius. At that point the radiators start to feel cold and the residents are sensitive to that. However, whilst they are “warmish” the residents don’t actually know if fresh hot water is being pumped around or not. The “return” of the heat pump monitor (even when not being pumped) is an approximate proxy for the radiator temperature.

My control algorithm uses a few heuristics to decide when to switch off the heat pump, such as “has it been at the desired flow for a few minutes” and “does the heat pump think it’s not worth putting any energy into the next cycle”. For turning back on it just looks at the “return” temperature.

One aspect of this is that the algorithm watches the trend of the cooling and predicts when it’ll come back on. On a number of occasions I’ve though to myself “ooh, it’s getting a bit cool now” only to go and look and see the prediction is for it to start in a couple of minutes or even that it has just started up. I’m the most sensitive person in the house to heat levels which is why my office is set to 23 Celsius - the radiator is 40cm from my chair.

The hysteresis includes the effective outdoor temperature in deciding what represents “cool” and how long it should delay turning on / off. In that way it’s a bit of an extension of the weather compensation.

The heat pump is of course turned on if the temperature gets really cold outside. We have glycol in the circuits though so 0Celsius isn’t a critical temperature for enabling it.

1 Like

Looking at the graphs, you seem to have some single data points for COP that are way out of range, hence the graph is basically flat, hiding the detail. These are surely anomalies and are maybe artefacts of the way the data is stored and processed? They only seem to occur when the pump is turning on or off.

@Bramco Hopefully the topic above will explain why it’s behaving that way and that it’s A Good Thing ™ :slight_smile:

I can see it’s a good thing to have the HP running more efficiently by not cycling. I have the heat bank set points set in such a way that our boiler when needed does long runs rather than cycling on and off.

However this still doesn’t answer why you suddenly get a COP value which can’t be realistic. You can’t put 1 unit of lekky in and get 300 times that out of a heat pump. So there’s something wrong somewhere. It has to be something to do with when and where you are measuring things.

Don’t get me wrong this isn’t a criticism, I think what you’ve shown us is great. But… something must be wrong in the measurements or we need to rewrite some physics.

I’d love to be proved wrong in which case someone will make a fortune by getting their HPs to run at a COP of 300 not 3.


1 Like

Yep, it does look wrong, but it’s because of the lag.

We’ve just heated the water and it’s still being pumped round so is providing “useful heat” in the way the MMSP measures it. On the last cycle we stop providing input power but there’s still warm water to pump around so it looks like we’ve done an amazing amount of work.

Here’s the actual stats coming from the MMSP. The last five columns are heat related - they measure in watt-hours.

You can see the “48” looking all lonely on one of the later rows. That’s the “useful heat produced” column and the “0” to the left of it is the amount of electricity we used in that cycle. FYI, the last column is the “how much electricity should we input on the next cycle” which the heat pump seems to take as a serving suggestion and not gospel.

Conversely, when starting up the CoP looks appalling because we’ve used electricity but the water is just starting to be pumped around.

This is why I usually average the CoP over 5 minutes - I just haven’t worked out how to do that in Emoncms yet.

Also, it looks as though you circulate your hot water, it gradually loses heat between operations of the HP.

@Bramco @borpin Hopefully the topic above explains how I’m using the sensors - notably as a proxy for the radiator temperature.

So “between operations” I don’t circulate the water.

Specifically, it was using 200W to pump the water round when the heating part was off. Seeing as most of the water was already in the radiators at that time there didn’t seem much point pumping the same water round and round. Especially because it also sent it outside to “anti-freeze” the heat pump. I didn’t buy a big lump of metal to sit outside so I could pay to keep it warm. There would be some water in the pipework radiating heat which would not be getting to the radiators. You could consider that “waste” or “poor man’s underfloor heating”, I’ll let you decide.

The other benefit has been that we don’t have to listen to the pump all the time. It’s ridiculously quiet where I live in the countryside and even the noise of a pump in the utility room is quite disruptive to the tranquillity. My brain thinks the noise is OK if the something is doing useful work (like the noisy tractors in the field next door) but can’t cope if there’s noise and no useful work.

Here’s where the sensors are…

Yes, I worked that out - as the water in the tank cools, the sensors are picking that up - hence the temp drop. The losses around the tank pipework are usually significant. I have double layered the pipes close to the tank where I can and next time I’ll make sure there is a lot more room around them to do it better!

Yep Brian, I’m losing heat in those pipes as you say. Notably it means they are roughly matching the radiators.

When I can get better monitoring of the rooms / radiators I could do as you’ve done and lag those pipes so they don’t lose heat.

1 Like

Now that we have some warmer days and on several the heatpump has basically wasted money activating on schedule at 2pm when the not-freezing outdoor air and the sunshine on our insulated-but-exposed house means we’re not yet getting cold, I’ve given the melcloud data collector python script on the emonPi control of the heatpump on/off switch. Wish me luck!

I’m using heat-thermostat mode as the “off” setting as a safeguard against freak weather and internet disconnection, with curve mode as the “on” setting. The logic after the await device.update() call looks like this:

if ((currentmode != 'heat-thermostat')
    and ((thishour not in range(4, 23))
         or (roomtemp > 20.5)
         or ((thistime > sunrise) and (thishour < 13)
             and (roomtemp > 19.9)))):
    await roomzone.set_operation_mode('heat-thermostat')
    await roomzone.set_target_temperature(16)
elif ((currentmode != 'curve')
      and (((thishour in range(4, 23))
            and ((roomtemp < 19)
                 or ((thistime > sunset)
                     and (roomtemp < 19.5))))
           or ((thishour == 5) and (roomtemp < 20.6)))):
    await roomzone.set_operation_mode('curve')

The temperature limits are best guesses from browsing the emoncms graphs of RoomTemperatureZone1 and OperationMode plotted together. The controller is central but not in the warmest room. I could also use the emonpi’s own temperature sensor, but I’m keeping it simple for now.

This should allow the humans to switch the curve on early or activate the thermostat if it’s borderline, but the emonpi will resume control once it crosses a temperature or time limit. The +/- buttons can still be used in curve mode and the offset will persist because I can’t see any way to reset it from melcloud.

It’s all wrapped in a big if not device.holiday_mode to skip it if we ever go away and I may yet try to add some logic (or interaction with emoncms) to detect and break excessive cycling, and to heat hot water at the most efficient time instead of simply when we usually want it.

Maybe that’s useful for someone, or maybe someone can tell me my mistake before we get cold!

Aha, that looks like my code from 2019-11 :slight_smile:

I was trying to leave control in the hands of the heat pump and setting the operation mode. In the end I found it was still too excitable so I stopped doing that and took full control (e.g. implementing the curve and walking the target temp up).

It’ll be interesting to see how you get along.

I’d be tempted to break your logic up so you can fiddle with it more confidently. In fact I use pytest to ensure the changes still mean it’ll come on when my wife wakes up.

BTW my blockers look like this:

def checkBlockers(self, deviceInfos: DeviceInfos) -> Optional[bool]:

    blockers: Iterable[Predicate[DeviceInfos]] = [

    for predicate in blockers:
        if predicate(deviceInfos):
   + " blocked any actions from being generated")
            return True
            logging.debug("Predicate " + predicate.__name__ + " returned False")

    return None

Oh, and “good luck!”

1 Like

Idle thought: I’ve just reimplemented the bimetallic thermostat from our old oil boiler in software, complete with the habitual evening/bedtime twiddling, but with a narrower latching range which probably compensates for the heat pump’s lower rad temp / longer warm-up time.

1 Like

Don’t you mean hysteresis - the temperature difference between turning on and turning off?

I think that’s different words for the same thing: hysteresis is the name of the general effect (not the actual difference I think?) and latching is the process in a mechanical thermostat that achieves it.

In 50 years in the industry, I’ve never heard “Latching” applied to the situation where a separate action is not required to ‘unlatch’ the mechanism - as in “Latching Emergency Stop Push Button”.

See - Thermostat “Typically the central system would be switched on when the temperature drops below the setpoint on the thermostat, and switched off when it rises above, with a few degrees of hysteresis to prevent excessive switching.” and that’s the sense and context in which I’ve always seen it used.

If you want to refer to commonly understood terms by different names, you should probably define what you mean each time.

I apologise if my term for it was not a familiar one, but as this shows, we don’t have a common understanding. It sounds like you’re in the heating industry, so that’s what it is to you. I trained as a mathematician/statistician and so I understand hysteresis as when a function’s output depends on some current state as well as the function inputs (see Hysteresis - Wikipedia which you linked).

Calling the difference between the on and off set-points “degrees of hysteresis” seems like an industry-specific shorthand: maybe that should be defined somewhere too, if knowing it is needed to take part in this community?

If you checked, you’d see that I’m a Chartered Electrical Engineer. I spent most of my career in the Controls & Automation field of electrical & electronic engineering.

Sorry for not searching on your name. But still a different industry to both my education and my work, so I think it’s understandable we don’t have completely common jargon, but I thought latching relays were a thing, but maybe they have a different official name to what non-specialists call them.

Nonetheless, I apologise for any confusion.

They are, and that’s exactly why I suggested the correct description for the action of a bi-metallic thermostat, and for that matter a microswitch, is hysteresis. In a latching relay, in one type, there will be “operating” coil, with a mechanical latch to retain the mechanism in the ‘operated’ position, and a second coil to release the latch and allow the mechanism to return to the non-operated state. In another type, the latching mechanism is magnetic, and then there are either two coils, or the coil is energised in the opposite polarity to release the relay (the “remanent” relay). The latching action requires a separate action to release, hysteresis is a property of one action - albeit in the opposite direction. Hence “degrees of hysteresis” because the thermostat is calibrated in degrees of temperature, in a microswitch the hysteresis is defined in mm of operator travel.

I don’t believe that is an accurate description of mathematical hysteresis (link to this site’s preferred dictionary), while the bimetallic thermostats I remember growing up decades ago simply used the pull of the rod bending caused by temperature change to overcome the (fairly weak) magnetism, but I’ll avoid both terms after this experience!

Now, back to heatpumps:

I’ve added the device.state == ‘defrost’ as a blocker to my routines alongside holiday mode. I’m not sure whether I need to add offline and missing device infos because I’m fairly sure my control program will die in a flaming traceback in those situations… :laughing:

I’ve also restructured the code so it changes mode based on whether roomtemp is in a target [min,max) range that is calculated by time of day, current and melcloud-forecast temperatures, and whether the system is in heat-water state, and added a blocker if we’ve already changed mode in the last hour as a basic protection against short-running. I won’t really know if this works well enough and saves any power until more cold weather next week.

I wonder about moving the logic to node-red and rewriting the melcloud commander-gatherer just to take commands from mqtt, or whether I should set up homeassistant, but homeassistant’s automations look less comprehensible to me than python code, I’m likely to be the only user and both seem like a lot of work reinventing this wheel I’ve just crafted. :wink: Maybe I’ll let it run for a month or two first.

1 Like

If, as a mathematician, you have a different definition to the engineering world, that’s fine - so long as you remember that you’ll only confuse everybody including yourself while you’re dealing with the engineering world.