3.x ‐ Usage example: Generic Optimizer ‐ heating domestic hot water during the cheapest hours of the day - masipila/openhab-spot-price-optimizer GitHub Wiki

Important note

Overview

This page gives an example how to use the GenericOptimizer class of the openhab-spot-price-optimizer module.

As the name suggests, the GenericOptimizer algorithms are generic and can be used for many different use cases such as water boilers or charging electric vehicles. This page shows how to find given number of cheapest hours of the day to heat the domestic hot water with a water boiler that can be controlled with openHAB. Further examples can be found on separate documentation page.

WARNING: Do not try to optimize the heating of domestic hot water too agressively.

  • The boiler should always have enough hours to reach the thermostate max temperature.
  • Legionella bacteria reproduces in temperatures between 20 - 45 ° celcius.
  • In Finland, there is a law that the water temperature in the boiler must always be at least 55 ° celcius to ensure that legionella bacteria will die.

Pre-requisites

Create two new Items

Create an Item 'BoilerHours'

image

Create an item 'BoilerControl'

image

Create a Rule 'BoilerOptimizer' to calculate the control points

  • This rule will create control points for each 15 minute period of the day
  • Control point value 1 means the power supply will be ON during and value 0 means that power supply will be OFF.
  • This Rule will be triggered whenever the Item BoilerHours changes.
  • We will also configure this Rule to be run after the spot prices have been fetched.

image

Version 3.x: Inline script action for the rule

Important This script works only on version 3.x of openHAB Spot Price Optimizer. See separate instructions for version 4.x of openHAB Spot Price Optimizer.

  • The following rule first reads the SpotPrice values from midnight to midnight
  • It then reads how many hours the boiler needs to be ON from the BoilerHours item
  • It then finds the cheapest consecutive period for this many hours.
  • All remaining hours will be blocked.
  • Finally, the control points will be saved to InfluxDB as BoilerControl.
// Load modules. Database connection parameters must be defined in config.js.
var { Influx } = require('openhab-spot-price-optimizer/influx.js');
var { GenericOptimizer } = require('openhab-spot-price-optimizer/generic-optimizer.js');

// Create services.
var influx = new Influx();
var optimizer = new GenericOptimizer();

//If the script is called after 14.00, optimize tomorrow. Otherwise optimize today.
var start = time.toZDT('00:00');
if (time.toZDT().isBetweenTimes('14:00', '23:59')) {
  start = start.plusDays(1);    
}
var stop = start.plusDays(1);

// Read spot prices from InfluxDB and pass them for the optimizer.
var prices = influx.getPoints('SpotPrice', start, stop);
optimizer.setPrices(prices);

// Read how many hours are needed from the BoilerHours item.
var item = items.getItem("BoilerHours");
var hours = Math.round(item.state);

// Optimize the control points and save them to the database.
optimizer.allowPeriod(hours);
optimizer.blockAllRemaining();
var points = optimizer.getControlPoints();
influx.writePoints('BoilerControl', points);

List of all optimization algorithms provided by GenericOptimizer

The GenericOptimizer optimizing class provides several optimization methods for different use cases. If you want to for example charge an electric vehicle so that you want to find the cheapest period between 21.00 and 06.00, that can easily be achieved. See more usage examples on a separate wiki page.

Invoke this Rule also after the spot prices have been fetched

  • The rule was defined to be run every time after the item BoilerHours changes. But what if this value is kept unchanged day after a day, what triggers this Rule to be executed?
  • The solution differs between versions 3.x and 4.x. of openHAB Spot Price Optimizer.

In version 3.x, the solution is to modify the previously created FetchSpotPrices Rule so that we execute the BoilerOptimizer rule as an additional action immediately after the spot prices have been fetched.

  • Go to edit the previously created FetchSpotPrices Rule and add the additional action as illustrated in the picture below. fetch-spot-price-execute-boiler-optimization

Create a Rule 'BoilerController' to toggle the boiler ON and OFF

  • This rule will run every 15 minutes and turn the boiler ON or OFF based on the current control point
  • If the boiler is currently OFF and the current control point is 1, the boiler will be turned ON and vice versa.

image

Version 3.x: Inline script action for the rule

// Load modules. Database connection parameters must be defined in config.js.
var { Influx } = require('openhab-spot-price-optimizer/influx.js');

// Create services.
var influx = new Influx();

// Read the control value for the current hour from the database.
var control = influx.getCurrentControl('BoilerControl');

// BoilerPower: Send the commands if state change is needed.
var BoilerPower = items.getItem("BoilerPower");
if (BoilerPower.state == "ON" && control == 0) {
  console.log("BoilerPower: Send OFF")
  BoilerPower.sendCommand('OFF');
}
else if (BoilerPower.state == "OFF" && control == 1) {
  console.log("BoilerPower: Send OFF")
  BoilerPower.sendCommand('ON');
}
else {
  console.log("BoilerPower: No state change needed")  
}

3.x: Script for deleting control points

When developing your solution and experimenting, you might want to delete points from your Influx database. The script below can be used for that.

// Load modules. Database connection parameters must be defined in config.js.
var { Influx } = require('openhab-spot-price-optimizer/influx.js');

// Create services.
var influx = new Influx();

// Delete BoilerControl points for today.
var start = time.toZDT('00:00');
var stop = start.plusDays(1);
influx.deletePoints('BoilerControl', start, stop);