Control a water heater and ground source heat pump based on cheap hours of spot priced electricity

I spotted this graph from the latest issue of Tekniikka & Talous

It supports your considerations that we don’t get any significant amount of passive heating between the beginning of November and end of February.

Cheers,
Markus

Should we start a sepate thread for savings discussion?

Just got my electricity bill for April 2023:

Consumption 854 kWh
Average cost 5,73 c/kWh
Margin 0,22 c/kWh
Monthly fee 4,36 €
Total bill 55,15€

References
Local energy company
Cost of energy 13,18 c/kWh
Monthly fee 2,5 €
Total cost would have been 115,06
Saved: 59,9€

Average spot price
April 6,661 c/kWh
Difference: 0,93 c/kWh = 14%
Saved: 7,95€

:+1:

That’s a great idea, please go ahead and create a thread for it and mentioned me and I’ll chime in!

Is it possible with OH scripting to make k dependent on the month, like so

Pseudocode

if currentMonth == (march or october) then k = 0,5
else if currentMonth == (april or september) then k = 1
else if currentMonth == (may or august) then k = 2
else if currentMonth == (june or july) then k = 3
else k = 0

or does this require external scripts and separate rules for each of the alternatives?

Yes, for sure it is. Google “how to get current month in javascript”

Using a building as a solar collector

In 4 season countries solar radiation heat varies over the seasons. During winter, even during a fully sunny day, the sun will not provide significant passive heating of buildings. However, from spring to fall the passive heating of buildings provided by the sun can cause waste of energy when both indoor heating and indoor cooling systems are running at the same time, which happens especially during spring and fall. Rather big savings can be achieved by proactively adapting the amount of heating used to the available incoming solar thermal energy. Thanks to OpenHAB and our community it is possible to use the solar energy forecast and electricity spot price to proactively turn down heating spenditure when there is surplus heat available from the sun.

The script below is my attempt at maximising the use of passive solar heating in a 4 season environment. No solar thermal collector or solar panel is used. Instead, the capability of the building itself to absorb solar thermal energy is exploited. The script relies on the OpenHAB Solar Forecast PV add on with a free solcast account and @masipila’s solution presented in this thread. Register a free account at solcast and install the Solar Forecast PV add-on and you should be good to go!

Edit: The script below was updated 1st of August to correct a couple of bugs.

console.log("Item heatingHours before solar inluded", items.getItem("heatingHours").state);

//Get energy forecast from Solcast
solarEnergy = items.getItem("Solcast_PV_Plane_Forecast_Tomorrow").state;

// calculate reduction coefficient from virtual solar panel max power and forecasted power
q = solarEnergy/1000;
console.log("Reduction coefficient:", q);

// replace JS dumb month numbering scheme starting from 0 with proper names for the months
var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];

// figure out current month
var d = new Date();
var currentMonth = months[d.getMonth()];

// Set max heating reduction hours, k, based on current month
if (currentMonth == "March" || currentMonth == "October") {
  k = 0.5;
} else if (currentMonth == "April"|| currentMonth == "September") {
  k = 1;
} else if (currentMonth == "May" || currentMonth == "August") {
  k = 2;
} else if (currentMonth == "June"|| currentMonth == "July") {
  k = 3;
} else {
  k = 0;
  console.log("It's winter");
};
console.log("It is now",currentMonth,"so max heating hour reduction thanks to solar is",k,"hours");

// calculate heating hours correction using the reduction coefficient and max reduction hours
m = q*k;
n = items.getItem("heatingHours").state - m;
console.log("Item heatingHours after solar included",items.getItem("heatingHours").state-m);

if (n < 0) {
  n = 0.01;
};
// update heating hours item
items.getItem("heatingHours").postUpdate(n);

Recently my Nibe F1226 heatpump has the two Shelly1 relay switches to switch between the 4 SG Ready modes. General question, can I break something on the heatpump when I would block the compressor for one whole month as long as the temperature is always above 5 degrees Celcius? This way I would like to save costs when I’m not in the house for one month.

1 Like

As I mentioned in my post 13, I disclaim all warranties and everybody is responsible for what they do with their devices.

A couple of things you might want to consider:

Nibe F1226 does not have a built-in vacation mode like for example F1245 so you need to do this yourself like you are now thinking. You might want to search from other forums what exactly does the vacation mode do in F1245 and then try to mimic that.

I would not switch off the pump completely. The valves might get stuck if they are unused for an extended period of time.

Regarding the heating, I would just drop the desired temperature from the Nibe menus.

One gotcha: F1226 has a setting “Minimum temperature for outgoing water” (should be menu 1.9.3). If my memory serves me well, the default is 22 celsius or at least that was the value it was set to me after installation. If compressor is blocked and the temperature drops below this, then Nibe will use electricity directly to ensure that the temperature does not drop below this. So you might want to consider adjusting this to a lower value like 17 or something.

Regarding domestic hot water, you can configure AUX1 to “block heating of domestic hot water” and that should do it. Remember that when you get back, there is a risk of legionella bacteria because the temperature of domestic hot water has dropped to the optimal temperature for the growth of legionella bacteria. So you do want to start the periodic increase as the first thing when you come back.

2 Likes

Thank you very much for the very useful information.

Currently I have on my Nibe F1226 the following configuration for “holiday” mode:

  • Menu 1.9.1 “Heating curve” 4 (normally 9)
  • Menu 1.9.3 “Minimum temperature for outgoing water” = 15°C (normally 20)
  • Menu 4.2 “Operation mode”=“auto”
  • Menu 4.9.2 (Auto mode setting): “Stop heating” = 12°C (normally 17), “Stop additional heat” 10°C (normally 15) → this will ensure that when the “average outdoor temperature” is greater than these values, no heating will be done
  • Menu 5.4 “AUX1” = “SG Ready A”
  • Menu 5.4 “AUX2” = “SG Ready B”

During “expensive hours” now SG Ready mode “Blocking” (A: Closed, B: Open) is used to block the “compressor” and “additional heating”. This doesn’t block “hot water production”.

In future I might consider trying out the following instead of the SG Ready modes:

  • Menu 5.4 “AUX1” = “External tariff blocking” → This can block “heating”, “additional heat”, “compressor”, and “hot water production”
  • Menu 1.9.2, “external adjustment” = +5°C
  • Menu 5.4 “AUX2” = “External adjustment” → This can “boost” the heating curve offset so that the house can be heated a bit more just before I come back home.

Thanks again, it is a lot of fun for me to try to understand the behaviour of the heatpump a bit better :slight_smile: I will try to understand the vacation mode in F1245 like you mentioned as well.

I found out setting the heating hours to zero is not a good idea, it confused the script, so here is an updated version that ensures heating hours never go to zero. The rest of the scripts will average the result to zero.

console.log("Item heatingHours before solar inluded", items.getItem("heatingHours").state);

//Get energy forecast from Solcast
solarEnergy = items.getItem("Solcast_PV_Plane_Forecast_Tomorrow").state;

// calculate reduction coeffficient from virtual solar panel max power and forecasted power
q = solarEnergy/1000;
console.log("Reduction coefficient:", q);

// replace JS dumb month numbering scheme starting from 0 with proper names for the months
const month = ["January","February","March","April","May","June","July","August","September","October","November","December"];

// figure out current month
const d = new Date();
let currentMonth = month[d.getMonth()];

// Set max heating reduction hours, k, based on current month
if (currentMonth == ("March"||"October")) { 
  k = 0.5;
} else if (currentMonth == ("April"||"September")) {
  k = 1;
} else if (currentMonth == ("May"||"August")) {
  k = 2.5;
} else if (currentMonth == ("June"||"July")) {
  k = 4;
} else {
  k = 0;
};
console.log("It is now",currentMonth,"so max heating hour reduction thanks to solar is",k,"hours");

// calculate heating hours correction using the reduction coefficient and max reduction hours
m = q*k;
n = items.getItem("heatingHours").state - m;
console.log("Item heatingHours after solar included",items.getItem("heatingHours").state-m);

if (n < 0) {
  n = 0.01;
};
// update heating hours item
items.getItem("heatingHours").postUpdate(n);

A hardware question, I own a nibe F1245. I read several posts using a relais to set the aux input. But as we’re saving energy, anyone investigated using an optocoupler to set it? I Imagine voltage and current for the input aren’t that high.

Nibe AUX pins use 3.3V low voltage.

Ok, and probably.no.more than a few mA. Well in range for an optocoupler. I can’t be the first to think of this, anyone tried it?

I have a Nibe 1245 and used a Chinese solid state relay for some time with no problems. Changed it to a wireless mechanical relay for convenience reasons.

1 Like

Hi I’m planning to develop a “real” Entso-E Binding add-on using Java. And maybe later FMI API binding. Any ideas how it should work on openHAB Things, Channels, Items, etc.

See

Which was superseded by Allow sending historic states and forecasts by J-N-K · Pull Request #3597 · openhab/openhab-core · GitHub

Markus

1 Like

Is there an easy way to get the average spot price for the forecasted day? I would like to have the value in an item to use it in a gauge.

Edit:
Sorted this out by myself: Copied the function in nibe.js that calculates average temperature and replaced fmi_forecasted_temperature with spot_price. Works like a charm.

I have implemented this in the graph that shows me the spot prices and control values, see screenshot below, which shows the average price as a dotted line.

The YAML looks like this:

component: oh-time-series
config:
  gridIndex: 0
  item: spot_price
  itemStyle:
    color: "#4E6AC4"
  lineStyle:
    opacity: 0.5
  markLine:
    data:
      - label:
          distance: -150
        name: Avg
        type: average
  name: Sähkön spottihinta
  step: middle
  type: line
  xAxisIndex: 0
  yAxisIndex: 0

1 Like

Will Markus’ cool “ground source heat pump” javascripts work directly in OpenHab 4.0, which now uses GraalJS/ECMAScript 2022? I wonder if it’s safe to upgrade OpenHab 3.0 to OpenHab 4.0 for that?

I haven’t had time to test that yet myself but I would also be super grateful for this information if somebody has tested this…