Data for the Heat Pump System: Heating Season 2016-2017

I update the documentation of measurement data [PDF] about twice a year. This post is to provide a quick overview for the past season.

The PDF also contains the technical configuration and sizing data. Based on typical questions from an ‘international audience’ I add a summary here plus some ‘cultural’ context:

Building: The house is a renovated, nearly 100-year old building in Eastern Austria: a typical so-called ‘Streckhof’ – an elongated, former small farmhouse. Some details are mentioned here. Heating energy for space heating of two storeys (185m2) and hot water is about 17.000-20.000kWh per year. The roof / attic had been rebuilt in 2008, and the facade was thermally insulated. However, the major part of the house is without an underground level, so most energy is lost via ground. Heating only the ground floor (75m2) with the heat pump reduces heating energy only by 1/3.

Climate: This is the sunniest region of Austria – the lowlands of the Pannonian Plain bordering Hungary. We have Pannonian ‘continental’ climate with low precipitation. Normally, monthly average temperatures in winter are only slightly below 0°C in January, and weeks of ‘ice days’ in a row are very rare.

Heat energy distribution and storage (in the house): The renovated first floor has floor loops while at the ground floor mainly radiators are used. Wall heating has been installed in one room so far. A buffer tank is used for the heating water as this is a simple ‘on-off’ heat pump always operating at about its rated power. Domestic hot water is heated indirectly using a hygienic storage tank.

Heating system. An off-the-shelf, simple brine-water heat pump uses a combination of an unglazed solar-air collector and an underwater water tank as a heat source. Energy is mainly harvested from rather cold air via convection.

Addressing often asked questions: Off-the-shelf =  Same type of heat pump as used with geothermal systems. Simple: Not-smart, not trying to be the universal energy management system, as the smartness in our own control unit and logic for managing the heat source(s). Brine: A mixture of glycol and water (similar to the fluid used with flat solar thermal collectors) = antifreeze as the temperature of brine is below 0°C in winter. The tank is not a seasonal energy storage but a buffer for days or weeks. In this post hydraulics is described in detail, and typical operating conditions throughout a year. Both tank and collector are needed: The tank provides a buffer of latent energy during ‘ice periods’ and it allows to harvest more energy from air, but the collector actually provides for about 75% of the total ambient energy the heat pump needs in a season.

Tank and collector are rather generously sized in relation to the heating demands: about 25m3 volume of water (total volume +10% freezing reserve) and 24m2 collector area.

The overall history of data documented in the PDF also reflects ongoing changes and some experiments, like heating the first floor with a wood stove, toggling the effective area of the collector used between 50% and 100%, or switching off the collector to simulate a harsher winter.

Data for the past season

Finally we could create a giant ice cube naturally. 14m3 of ice had been created in the coldest January since 30 years. The monthly average temperature was -3,6°C, 3 degrees below the long-term average.

(Re the oscillations of the ice volume are see here and here.)

We heated only the ground floor in this season and needed 16.600 kWh (incl. hot water) – about the same heating energy as in the previous season. On the other hand, we also used only half of the collector – 12m2. The heating water inlet temperatures for radiators was even 37°C in January.

For the first time the monthly performance factor was well below 4. The performance factor is the ratio of output heating energy and input electrical energy for heat pump and brine pump. In middle Europe we measure both energies in kWh 😉 The overall seasonal performance factor was 4,3.

The monthly performance factor is a bit lower again in summer, when only hot water is heated (and thus the heat pump’s COP is lower because of the higher target temperature).

Per day we needed about 100kWh of heating energy in January, while the collector could not harvest that much:

In contrast to the season of the Ice Storage Challenge, also the month before the ‘challenge’ (Dec. 2016) was not too collector-friendly. But when the ice melted again, we saw the usual large energy harvests. Overall, the collector could contribute not the full ‘typical’ 75% of ambient energy this season.

(Definitions, sign conventions explained here.)

But there was one positive record, too. In a hot summer of 2017 we consumed the highest cooling energy so far – about 600kWh. The floor loops are used for passive cooling; the heating buffer tank is used to transfer heat from the floor loops to the cold underground tank. In ‘colder’ summer nights the collector is in turn used to cool the tank, and every time hot tap water is heated up the tank is cooled, too.

Of course the available cooling power is just a small fraction of what an AC system for the theoretical cooling load would provide for. However, this moderate cooling is just what – for me – makes the difference between unbearable and OK on really hot days with more than 35°C peak ambient temperature.

Hacking My Heat Pump – Part 2: Logging Energy Values

In the last post, I showed how to use Raspberry Pi as CAN bus logger – using a test bus connected to control unit UVR1611. Now I have connected it to my heat pump’s bus.

Credits for software and instructions:

Special thanks to SK Pang Electronics who provided me with CAN boards for Raspberry Pi after having read my previous post!!

CAN boards for Raspberry Pi, by SK Pang

CAN extension boards for Raspberry Pi, by SK Pang. Left: PiCAN 2 board (40 GPIO pins), right: smaller, retired PiCAN board with 26 GPIO pins – the latter fits my older Pi. In contrast to the board I used in the first tests, these have also a serial (DB9) interface.

Wiring CAN bus

We use a Stiebel-Eltron WPF 7 basic heat pump installed in 2012. The English website now refers to model WPF 7 basic s.

The CAN bus connections described in the German manual (Section 12.2.3) and the English manual (Wiring diagram, p.25) are similar:

Stiebel-Eltron WPF 7 basic - CAN bus connections shown in German manual

CAN bus connections inside WPF 7 basic heat pump. For reference, see the description of the Physical Layer of the CAN protocol. Usage of the power supply (BUS +) is optional.

H, L and GROUND wires from the Pi’s CAN board are connected to the respective terminals inside the heat pump. I don’t use the optional power supply as the CAN board is powered by Raspberry Pi, and I don’t terminate the bus correctly with 120 Ω. As with the test bus, wires are rather short and thus have low resistance.

Stiebel-Eltron WPF 7 basic - CAN bus connections inside the heat pump, cable from Raspberry Pi connected.

Heat pump with cover removed – CAN High (H – red), Low (L – blue), and Ground (yellow) are connected. The CAN cable is a few meters long and connects to the Raspberry Pi CAN board.

In the first tests Raspberry Pi had the privilege to overlook the heat pump room as the top of the buffer tank was the only spot the WLAN signal was strong enough …

Raspberry Pi, on top of the buffer tank

Typical, temporary nerd’s test setup.

… or I used a cross-over ethernet cable and a special office desk:

Working on the heat pump - Raspberry Pi adventures

Typical, temporary nerd’s workplace.

Now Raspberry Pi has its final position on the ‘organic controller board’, next to control unit UVR16x2 – and after a major upgrade to both LAN and WLAN all connections are reliable.

Raspberry Pi with PiCAN board from SK Pang and UVR16x2

Raspberry Pi with PiCAN board from SK Pang and UVR16x2 control unit from Technische Alternative (each connected to a different CAN bus).

Bringing up the interface

According to the bit rate of Stiebel-Eltron’s bus is 20000 bit/s; so the interface is activated with:

sudo ip link set can0 type can bitrate 20000
sudo ifconfig can0 up

Watching the idle bus

First I was simply watching with sniffer Wireshark if the heat pump says anything without being triggered. It does not – only once every few minutes there are two packets. So I need to learn to talk to it.

Learning about CAN communications

SK Pang provides an example of requesting data using open source tool cansend: The so-called CAN ID is followed by # and the actual data. This CAN ID refers to an ‘object’ – a set of properties of the device, like the set of inputs or outputs – and it can contain also the node ID of the device on the bus. There are many CAN tutorials on the net, I found this (German) introduction and this English tutorial very useful.

I was able to follow the communications of the two nodes in my test bus as I knew their node numbers and what to expect – the data logger would ask the controller for a set of configured sensor outputs every minute. Most packets sent by either bus member are related to object 480, indicating the transmission of a set of values (Process Data Exchange Objects, PDOs. More details on UVR’s CAN communication, in German)

Network trace on test CAN bus: UVR1611 and BL-NET

Sniffing test CAN bus – communication of UVR1611 (node no 1) and logger BL-NET (node number 62 = be). Both devices use an ID related to object ID 480 plus their respective node number, as described here.

So I need to know object ID(s) and properly formed data values to ask the heat pump for energy readings – without breaking something by changing values.

Collecting interesting heat pump parameters for monitoring

I am very grateful for Jürg’s CAN tool can_scan that allow for querying a Stiebel-Eltron heat pump for specific values and also for learning about all possible parameters (listed in so-called Elster tables).

In order to check the list of allowed CAN IDs used by the heat pump I run:

./can_scan can0 680

can0 is the (default) name of the interface created earlier and 680 is my (the sender’s) CAN ID, one of the IDs allowed by can_scan.

Start of output:

elster-kromschroeder can-bus address scanner and test utility
copyright (c) 2014 Jürg Müller, CH-5524

scan on CAN-id: 680
list of valid can id's:

  000 (8000 = 325-07)
  180 (8000 = 325-07)
  301 (8000 = 325-07)
  480 (8000 = 325-07)
  601 (8000 = 325-07)

In order to investigate available values and their meaning I run can_scan for each of these IDs:

./can_scan can0 680 180

Embedded below is part of the output, containing some of the values (and /* Comments */). This list of parameters is much longer than the list of values available via the display on the heat pump!

I am mainly interested in metered energies and current temperatures of the heat source (brine) and the ‘environment’ – to compare these values to other sensors’ output:

elster-kromschroeder can-bus address scanner and test utility
copyright (c) 2014 Jürg Müller, CH-5524

0001:  0000  (FEHLERMELDUNG  0)
0003:  019a  (SPEICHERSOLLTEMP  41.0)
0005:  00f0  (RAUMSOLLTEMP_I  24.0)
0006:  00c8  (RAUMSOLLTEMP_II  20.0)
0007:  00c8  (RAUMSOLLTEMP_III  20.0)
0008:  00a0  (RAUMSOLLTEMP_NACHT  16.0)
0009:  3a0e  (UHRZEIT  14:58)
000a:  1208  (DATUM  18.08.)
000c:  00e9  (AUSSENTEMP  23.3) /* Ambient temperature */
000d:  ffe6  (SAMMLERISTTEMP  -2.6)
000e:  fe70  (SPEICHERISTTEMP  -40.0)
0016:  0140  (RUECKLAUFISTTEMP  32.0) /* Heating water return temperature */
01d4:  00e2  (QUELLE_IST  22.6) /* Source (brine) temperature */
/* Hot tap water heating energy MWh + kWh */
/* Daily totaly */   
092a:  030d  (WAERMEERTRAG_WW_TAG_WH  781)
092b:  0000  (WAERMEERTRAG_WW_TAG_KWH  0)
/* Total energy since system startup */
092c:  0155  (WAERMEERTRAG_WW_SUM_KWH  341)
092d:  001a  (WAERMEERTRAG_WW_SUM_MWH  26)
/* Space heating energy, MWh + kWh */
/* Daily totals */
092e:  02db  (WAERMEERTRAG_HEIZ_TAG_WH  731)
/* Total energy since system startup */
0930:  0073  (WAERMEERTRAG_HEIZ_SUM_KWH  115)
0931:  0027  (WAERMEERTRAG_HEIZ_SUM_MWH  39)

Querying for one value

The the heating energy to date in MWh corresponds to index 0931:

./can_scan can0 680 180.0931

The output of can_scan already contains the sum of the MWh (0931) and kWh (0930) values:

elster-kromschroeder can-bus address scanner and test utility
copyright (c) 2014 Jürg Müller, CH-5524

value: 0027  (WAERMEERTRAG_HEIZ_SUM_MWH  39.115)

The network trace shows that the logger (using ID 680) queries for two values related to ID 180 – the kWh and the MWh part:

Network trace on heat pump's CAN bus: Querying for space heating energy to date.

Network trace of Raspberry Pi CAN logger (ID 680) querying CAN ID 180. Since the returned MWh value is the sum of MWh and kWh value, two queries are needed. Detailed interpretation of packets in the text below.

Interpretation of these four packets – as explained on Jürg’s website here and here in German:

00 00 06 80 05 00 00 00 31 00 fa 09 31  
00 00 01 80 07 00 00 00 d2 00 fa 09 31 00 27
00 00 06 80 05 00 00 00 31 00 fa 09 30 
00 00 01 80 07 00 00 00 d2 00 fa 09 30 00 73
|---------| ||          |---| || |---| |---|
1)          2)          3)    4) 5)    6)

1) CAN-ID used by the sender: 180 or 680 
2) No of bytes of data - 5 for queries, 8 for replies
3) CAN ID of the communications partner and type of message. 
For queries the second digit is 1. 
Pattern: n1 0m with n = 180 / 80 = 3 (hex) and m = 180 mod 7 = 0 
(hex) Partner ID = 30 * 8 (hex) + 00 = 180 
Responses follow a similar pattern using second digit 2: 
Partner ID is: d0 * 8 + 00 = 680 
4) fa indicates that the Elster index no is greater equal ff. 
5) Index (parameter) queried for: 0930 for kWh and 0931 for MWh
6) Value returned 27h=39,73h=115

I am not sure which node IDs my logger and the heat pump use as the IDs. 180 seems to be an object ID without node ID added while 301 would refer to object ID + node ID 1. But I suppose with two devices on the bus only, and one being only a listener, there is no ambiguity.

Logging script

I found all interesting indices listed under CAN ID 180; so am now looping through this set once every three minutes with can_scan, cut out the number, and add it to a new line in a text log file. The CAN interfaces is (re-)started every time in case something happens, and the file is sent to my local server via FTP.

Every month a new log file is started, and log files – to be imported into my SQL Server  and processed as log files from UVR1611 / UVR16x2, the PV generator’s inverter, or the smart meter.

(Not the most elegant script – consider it a ‘proof of concept’! Another option is to trigger the sending of data with can_scan and collect output via can_logger.)

Interesting to-be-logged parameters are added to a ‘table’ – a file called indices:



# Define folders

# FTP parameters

# Exit if scripts not found
if ! [ -d $scriptsdir ] 
    echo Directory $scriptsdir does not exist!
    exit 1

# Create log dir if it does not exist yet
if ! [ -d $logdir ] 
    mkdir $logdir

sleep 5

echo ======================================================================

# Start logging
while [ 0 -le 1 ]

# Get current date and start new logging line
now=$(date +'%Y-%m-%d;%H:%M:%S')
year=$(date +'%Y')
month=$(date +'%m')

# Create a new file for every month, write header line
# Create a new file for every month
if ! [ -f $logfilepath ] 
    headers="Datum Uhrzeit"
    while read indexline
        header=$(echo $indexline | cut -d" " -f2) 
    done < $indexfile ; echo "$headers" > $logfilepath 

# (Re-)start CAN interface
    sudo ip link set can0 type can bitrate 20000
    sudo ip link set can0 up

# Loop through interesting Elster indices
while read indexline
    # Get output of can_scan for this index, search for line with output values
    index=$(echo $indexline | cut -d" " -f1)
    value=$($scriptsdir/./can_scan can0 680 180.$index | grep "value" | replace ")" "" | grep -o "\<[0-9]*\.\?[0-9]*$" | replace "." ",")     
    echo "$index $value"     

    # Append value to line of CSV file     
done < $indexfile ; echo $line >> $logfilepath

# echo FTP log file to server
ftp -n -v $ftphost << END_SCRIPT
user $ftpuser $ftppw
cd RPi
lcd $logdir
put $logfile

echo "------------------------------------------------------------------"

# Wait - next logging data point
sleep 180

# Runs forever, use Ctrl+C to stop

In order to autostart the script I added a line to the rc.local file:

su pi -c '/CAN_SCRIPTS/pkt_can_monitor'

Using the logged values

In contrast to brine or water temperature heating energies are not available on the heat pump’s CAN bus in real-time: The main MWh counter is only incremented once per day at midnight. Then the daily kWh counter is added to the previous value.

Daily or monthly energy increments are calculated from the logged values in the SQL database and for example used to determine performance factors (heating energy over electrical energy) shown in our documentation of measurement data for the heat pump system.

How Does It Work? (The Heat Pump System, That Is)

Over the holidays I stayed away from social media, read quantum physics textbooks instead, and The Chief Engineer and I mulled over the fundamental questions of life, the universe and everything. Such as: How to explain our heat pump system?

Many blog postings were actually answers to questions, and am consolidating all these answers to frequently asked questions again in a list of such answers. However, this list has grown quickly.

An astute reader suggested to create an ‘animation’ of the gradual evolution of the system’s state. As I learned from discussions, one major confusion was related to the role of the solar collector and the fact that you have to factor in the history of the heat source: This is true for every heat pump system that uses a heat source that can be ‘depleted’, in contrast to a flow of ground water at a constant temperature for example. With the latter, the ‘state’ of the system only depends on the current ambient temperature, and you can explain it in a way not too different from pontificating on a wood or gas boiler.

One thing you have to accept though is how a heat pump as such works: I have given up to go into thermodynamical details, and I also think that the refigerator analogy is not helpful. So for this pragmatic introduction a heat pump is just a device that generates heating energy as an output, the input energy being electrical energy and heat energy extracted from a rather cold heat source somewhere near the building. For 8kW heating power you need about 2kW electrical energy and 6kW ambient energy. The ratio of 8kW and 2kW is called the coefficient of performance.

What the typical intro to heat pumps in physics textbooks does not point out is that the ambient heat source actually has to be able to deliver that input energyduring a whole heating season. There is no such thing as the infinite reservoir of energy usually depicted as a large box. Actually, the worse the performance of a heat pump is – the ratio of output heat energy and input electrical energy, the smaller are the demands on the heat source. The Chief Engineer has coined the term The Heat Source Paradox for this!

The lower the temperature of the heat source, the smaller the coefficient of performance is: So if you run an air source heat pump in mid-winter (using a big ventilator) then less energy is extracted from that air source than a geothermal heat pump would extract from ground. But if you build a geothermal heat source that’s too small in relation to a building’s heating demands, you see the same effect: Ground freezes, source temperature decreases, performance decreases, and you need more electrical energy and less ambient energy.

I am harping on the role of the heat source as the whole point of our ‘innovation’ is our special heat source that has two components, both of them being essential: An unglazed solar / air collector and an underground water / ice tank plus the surrounding ground. The collector allows to replenish the energy stored in the tank quickly, even in winter: Air temperature just needs to be some degrees warmer than the cold brine. The tank is a buffer: When no energy is harvested by the collector at ambient temperatures below 0°C, water freezes and releases latent heat. So you can call that an air heat pump with a huge, silent and mainentance-free ‘absorber’ plus a buffer that provides energy for periods of frost and that allows for storing all the energy you don’t need immediately. Ground does provide some energy as well, and I am planning to post about my related simulations.(*) It can be visualized as an extension of the ice / water energy storage into the surroundings. But the active volume or area of ground is smaller than for geothermal systems as most of the ambient energy actually comes from the solar / air collector: The critical months in our climate are Dec-Jan-Feb: Before and after, the collector would be sufficient as the only heat source. In the three ‘ice months’ water is typically frozen in the tank, but even then the collector provides for 75-80% of the ambient energy needed to drive the heat pump.(*)

(*) Edit: This post written in 2017 show how much energy is stored / exchanged by each component. An overview of essential numbers is given here; emphasis on the volume of ice – which is compared to simulations here.

Components are off-the-shelf products, actually rather simple and cheap ones, such as the most stupid, non-smart brine-water heat pump. What is special is 1) the arrangement of the heat exchanger in the water tank and 2) the custom control logic, that is programming of the control unit.

So here is finally the series of images of the system’s state, shown in a gallery and with captions: You can scroll down to see the series embedded in the post, or click on the first image to see an enlarged view and then click through the slide-show.

More information on the system (technical data, sizing) and measurement data since 2012 can be found in this documentation – updated every few months.

Information for German readers: This post contains the German version of this slide-show.

Heat Pump System Data: Three Seasons 2012 – 2015

We have updated the documentation of monthly and seasonal measurement data – now including also the full season September 2014 to August 2015.

The overall Seasonal Performance Factor was 4,4 – despite the slightly lower numbers in February and March, when was the solar collector was off during the Ice Storage Challenge.

Edit: I have learned from a question that the SPF is also calculated in BTU/Wh. ‘Our’ SPF uses the same units in nominator and denominator, so 4,4 is in Wh/Wh. The conversion factor is about 3,4 (note that I use a decimal comma BTW), so our SPF [kWh/kWh] is equivalent to an SPF [BTU/Wh] ~ 15.

Monthly Performance Factor, Heat Pump System

Monthly heating energy provided by the heat pump – total of both space heating and hot water water, related electrical input energy, and the ratio = monthly performance factor. The SPF is in kWh/kWh.

The SPF determines economics of heating with a heat pump.

It’s time to compare costs again, based on current minimum prices of electricity and natural gas in our region in Austria (published by regulator e-control):

  • We need about 20.000 kWh (*) of heating energy per year.
  • Assuming a nearly perfect gas boiler with an efficiency of 95%, we would need about 21.050 kWh of gas.
  • Cost of natural gas incl. taxes, grid fees: ~ 0,0600 € / kWh
  • Yearly energy costs for heating with gas would be: € 1.260
  • Given an SPF of 4,4 for the heat pump, 20.000 kWh heating energy demands translate to 4.545 kWh of electrical energy.
  • Costs of electricity incl. taxes, grid: ~ 0,167 € / kWh
  • Yearly energy costs for heating with the heat pump: € 760
  • Yearly savings with the heat pump: € 500 or 40% of the costs of gas.

(*) As indicated in the PDF, In the past year only the ground floor was heated by the heat pump. So we needed only 13.300 kWh. In the first floor we got rid of the remainders of the old roof truss. The season 2012/2013 was more typical, requiring about 19.700 kWh.

The last winter was not too extreme – we needed 100 kWh maximum heating energy per day. The collector was capable of harvesting about 50 kWh / day:

Daily energy balances, heat pump system, season 2014-2015

Daily energies: 1) Heating energy delivered by the heat pump. Heating energy = electrical energy + ambient energy from the tank. 2) Energy supplied by the collector to the water tank, turned off during the Ice Storage Challenge. Negative collector energies indicate cooling of the water tank by the collector during summer nights. 200 kWh peak in January: due to the warm winter storm ‘Felix’.

Ice formation in this season was mainly triggered by turning off the solar collector deliberately. As soon as we turn the collector on again in March the ice was melted quickly, and the temperature increased to the set value of 8°C – a value picked deliberately to prepare for cooling in summer:

Temperatures and ice formation, heat pump system, season 2014-2015

Daily averages of the air temperature and the temperature in the water tank plus volume of ice created by extracting heat from the heat source (water tank).

Further reading / about the system:
I am maintaining a list of answers to Frequently Asked Questions here.

How to Evaluate a Heat Pump’s Performance?

The straight-forward way is to read off two energy values at the end of a period – day, month, or season:

  1. The electrical energy used by the heat pump
  2. and the heating energy delivered.

The Seasonal Performance Factor (SPF) is the ratio of these – the factor the input electrical energy is ‘multiplied with’ to yield heating energy. The difference between these two energies is supplied by the heat source – the underground water tank / ‘cistern’ plus solar collector in our setup.

But there might not be a separate power meter just for the heat pump’s compressor. Fortunately, performance factors can also be evaluated from vendors’ datasheets and measured brine / heating water temperatures:

Datasheets provide the Coefficient of Performance (COP) – the ‘instantaneous’ ratio of heating power and electrical power. The COP decreases with increasing temperature of the heating water, and with decreasing temperature of the source  – the brine circuit immersed in the cold ice / water tank. E.g when heating the water in floor loops to 35°C the COP is a bit greater than 4 if the water in the underground tank is frozen (0°C). The textbook formula based on Carnot’s ideal process for thermodynamic machines is 8,8 for 0°C/35°; realistic COPs are typically by about factor of 2 lower.

Heat Pump Performance, from Datasheets

COPs, eletrical power (input) and heating power (output) of a ‘7 kW’ brine / water heat pump. Temperatures in the legend are heating water infeed temperatures – 35°C as required by floor loops and 50°C for hot water heating.

If you measure the temperature of the brine and the temperature of the heating water every few minutes, you can determine the COP from these diagrams and take averages for days, months, or seasons.

But should PF and average COP actually be the same?

Average power is total energy divided by time, so (with bars denoting averages):

\text{Performance Factor } = \frac {\text{Total Heating Energy } \mathnormal{E_{H}}} {\text{Total Electrical Energy } \mathnormal{E_{E}}} = \frac {\text{Average Heating Power } \mathnormal{\bar{P}_{H}}} {\text{Average Electrical Power }\mathnormal{\bar{P}_{E}} }

On the other hand the average COP is calculated from data taken at many different times. At any point of time t,

\text{Coefficient of Performance(t)} = \frac {\text{Heating Power }P_{H}(t))} {\text{Electrical Power } P_{E}(t))}

Having measured the COP at N times, the average COP is thus:

\overline{COP}(t) = \frac {1}{N} \sum \frac{P_{H}(t)}{P_{E}(t)} = \overline{\frac{P_{H}(t)}{P_{E}(t)}}

\overline{\frac{P_{H}(t)}{P_{E}(t)}} is not necessarily equal to \frac{\overline{P_{H}}}{\overline{P_{E}}}

When is the average of ratios equal to the ratios of the averages?

If electrical power and heating power would fluctuate wildly we would be in trouble. Consider this hypothetical scenario of odd non-physical power readings:

  • PH = 10, PE = 1
  • PH = 2, PE = 20

The ratio of averages is: (10 + 2) / (1 + 20) = 12 / 21 = 0,57
The average of ratios is: (10/1 + 2/20) / 2 = (10 + 0,1) / 2 = 5,05

Quite a difference. Good that typical powers look like this:

Measured heating power, electrical power, COP (heat pump)

Powers measured on 2015-02-20 . Two space heating periods with a COP between 4 and 5, and one heating hot water cycle: the COP gradually decreases as heating water temperature increases.

Powers change only by a fraction of their absolute values – the heat pump is basically ON or OFF.  When these data were taken in February, average daily ambient temperature was between 0°C and 5°C, and per day about 75kWh were used for space heating and hot water. Since heat pump output is constant, daily run times change with heating demands.

Results for the red hot tap water heating cycle:

  • Performance Factor calculated from energies: 3,68
  • Average COP: 3,76.

I wanted to know how much powers are allowed to change without invalidating the average COP method:

Electrical power and heating power rise / fall about linearly, so they can be described by two parameters: Initial powers when the heat pump is turned on, and the slope of the curve or relative change of power within on cycle. The Performance Factor is determined from energies, the areas of trapezoids under the curves. For calculating the COP the ratio needs to be integrated, which results in a not so nice integral.

The important thing is that COP and PF are proportional to the ratio of inital powers and their relative match only depends on the slopes of the heating power and electrical power curves. As long as the relative increase / decrease of those powers is significantly smaller than 1, the difference in performance indicators is just a few percent. In the example curve, the heating energy decreases by 15%, while electrical energy increases by 52% – performance indicators would differ by less than 2%. This small difference is not too sensitive to changes in slopes.

All is well.

Solar collector, spring 2015.

Happily harvesting ambient energy.


Detailed monthly and seasonal performance data are given in this document.