UI example: Control parameters page - masipila/openhab-spot-price-optimizer GitHub Wiki

The examples on other wiki pages include two use cases for openhab-spot-price-optimizer:

The controlling of the boiler involved creating an Item BoilerHours which defines how many hours the water boiler needs to be ON.

While the HeatingPeriodOptimizer taking many aspects into account while optimizing the heating, it might be sometimes necessary to manually adjust the control points and force the heating ON or OFF for given times of the day.

This wiki page shows how to create an openHAB Page shown in the screenshot below which allows to modify the value of the BoilerHours Item and to force the a heating hour ON or OFF.

image

Create Items for forcing the heat pump compressor control points ON or OFF

Before we proceed to creating the actual openHAB Page, let's create two new Items for selecting the times that the heat pump compressor is forced ON or OFF.

Create two Items called HeatPumpCompressorForceOn and HeatPumpCompressorForceOff so that the type of these items is DateTime. You can also add category, semantic class and semantic property for these items as shown in the screenshot below.

image

Create a new Control Parameters page and add it to the sidebar

  • Go to settings and create a new layout page
  • Give a name to the page, for example Control Parameters and make it visible in the sidebar
  • The openHAB user interface for configuring the page content may feel a bit confusing in the beginning, but we want to create -- A Block -- Which will contain a Row -- Which will contain a Column -- And the Column will contain a Stepper Card which has the plus and minus buttons to adjust the value of the BoilerHours Item

For the date and time pickers for heat pump compressor, we want to create

  • A Block
  • Which will contain a Row
  • Which will contain a Column
  • And the Column will contain a Input card for selecting a datetime on the local timezone to update HeatPumpCompressorForceOn and HeatPumpCompressorForceOff Items

image

Page configuration as code

If you wish, you can copy-paste the code of the whole page as a code instead of configuring it with the Design editor.

config:
  label: Control Parameters
  sidebar: true
blocks:
  - component: oh-block
    config:
      title: Boiler & Domestic Hot Water
    slots:
      default:
        - component: oh-grid-row
          config: {}
          slots:
            default:
              - component: oh-grid-col
                config: {}
                slots:
                  default:
                    - component: oh-stepper-card
                      config:
                        item: BoilerHours
                        max: 24
                        min: 0
                        step: 0.25
                        title: Boiler hours
  - component: oh-block
    config:
      title: Heating
    slots:
      default:
        - component: oh-grid-row
          config: {}
          slots:
            default:
              - component: oh-grid-col
                config: {}
                slots:
                  default:
                    - component: oh-input-card
                      config:
                        type: datetime-local
                        inputmode: text
                        title: "Heat Pump Compressor: Force hour ON"
                        footer: =items.HeatPumpCompressorForceOn.state
                        name: HeatPumpCompressorForceOn
                        sendButton: true
                        clearButton: true
                        item: HeatPumpCompressorForceOn
  - component: oh-block
    config: {}
    slots:
      default:
        - component: oh-grid-row
          config: {}
          slots:
            default:
              - component: oh-grid-col
                config: {}
                slots:
                  default:
                    - component: oh-input-card
                      config:
                        type: datetime-local
                        inputmode: text
                        title: "Heat Pump Compressor: Force hour OFF"
                        footer: =items.HeatPumpCompressorForceOff.state
                        name: HeatPumpCompressorForceOff
                        sendButton: true
                        clearButton: true
                        item: HeatPumpCompressorForceOff
masonry: null
grid: []
canvas: []

Trigger the Rules when the Items on the Control Parameters page are changed

The Control Parameters page is only an user interface for changing the values of the BoilerHours, HeatPumpCompressorForceOn and HeatPumpCompressorForceOff items. The Items don't do anything by themselves, you need to trigger a Rule when the values of these Items change.

Run the BoilerOptimizer Rule when the BoilerHours item change

Let's have a closer look at the example page for optimizing the boiler to the cheapest hours.. The Rule that we created on that page looks like this:

297786552-54faa316-2981-4112-b7bf-9f1a3a91e4d5

So we have already configured the Rule BoilerOptimizer to be run every time when the Item BoilerHours change. In other words, there is nothing more that we need to do, this Control Parameters page only provides a nice user interface with a Stepper Card to update the BoilerHours Item!

Create a new Rule to force Heat Pump Compressor ON

To force the Heat Pump Compressor ON or OFF, we do not want to run the whole optimization script again. Instead, we want to write control points for the Item HeatPumpCompressorControl. So let's create a new Rule which is run when the Item HeatPumpCompressorForceOn is changed. This is the Item that we created above and which we can now update on the Control Parameters page.

image

The Script Action for this Rule is below (scripting language is again ECMAScript). It reads the datetime from the Item HeatPumpForcedOn and writes 4 control points to the database with value 1, which means that the heat pump compressor is allowed to run.

Script for version 3.x of openHAB Spot Price Optimizer

The following script works with version 3.x of openHAB Spot Price Optimizer. See a separate script below for version 4.x

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

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

// Read the hour that should be forced ON from the Item.
var item = items.getItem("HeatPumpCompressorForceOn");
var datetime = item.state;

// Prepare 4 control points for each 15 minute slots of the given hour.
var points = [];
var resolution = time.Duration.parse('PT15M');

for (var i=0; i < 4; i++) {
  var point = {
    datetime: time.toZDT(datetime).plus(resolution.multipliedBy(i)),
    value: 1
  }
  points.push(point);
}

// Write the control point to the database.
var item = 'HeatPumpCompressorControl';
influx.writePoints(item, points);

Script for version 4.x of openHAB Spot Price Optimizer

The following script works with version 4.x of openHAB Spot Price Optimizer. See a separate script above for version 3.x

// Read the hour that should be forced ON.
var item = items.getItem("HeatPumpCompressorForceOn");
var datetime = time.toZDT(item.state);

// Get minutes and compute how many minutes needs to be added to reach next 15 min.
var minutes = datetime.minute();
var remainder = minutes % 15;
var minutesToAdd = remainder === 0 ? 0 : (15 - remainder);
var rounded = datetime.plusMinutes(minutesToAdd).withSecond(0).withNano(0);

// Prepare the control point timeseries.
var ts = new items.TimeSeries('REPLACE');
var resolution = time.Duration.parse('PT15M');
for (i=0; i < 4; i++) {
  var zdt = rounded.plus(resolution.multipliedBy(i));
  var value = "1";
  ts.add(zdt, value);
}

// Write the control points to the database.
var controlItem = items.getItem("HeatPumpCompressorControl");
controlItem.persistence.persist(ts);

Create a new Rule to force Heat Pump Compressor OFF

We also need to create a Rule which write control points when the item HeatPumpForcedOff is updated on the Control Parameters page.

image

The Script Action (scripting language is again ECMAScript) for this Rule is below. It reads the datetime from the Item HeatPumpForcedOff and writes 4 control points to the database with value 0, which means that the heat pump compressor is not allowed to run.

Script for version 3.x of openHAB Spot Price Optimizer

The following script works with version 3.x of openHAB Spot Price Optimizer. See a separate script below for version 4.x

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

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

// Read the hour that should be forced OFF from the Item.
var item = items.getItem("HeatPumpCompressorForceOff");
var datetime = item.state;

// Prepare 4 control points for each 15 minute slots of the given hour.
var points = [];
var resolution = time.Duration.parse('PT15M');

for (var i=0; i < 4; i++) {
  var point = {
    datetime: time.toZDT(datetime).plus(resolution.multipliedBy(i)),
    value: 0
  }
  points.push(point);
}

// Write the control points to the database.
var item = 'HeatPumpCompressorControl';
influx.writePoints(item, points);

Script for version 4.x of openHAB Spot Price Optimizer

The following script works with version 4.x of openHAB Spot Price Optimizer. See a separate script above for version 3.x

// Read the hour that should be forced OFF.
var item = items.getItem("HeatPumpCompressorForceOff");
var datetime = time.toZDT(item.state);

// Get minutes and compute how many minutes needs to be added to reach next 15 min.
var minutes = datetime.minute();
var remainder = minutes % 15;
var minutesToAdd = remainder === 0 ? 0 : (15 - remainder);
var rounded = datetime.plusMinutes(minutesToAdd).withSecond(0).withNano(0);

// Prepare the control point timeseries.
var ts = new items.TimeSeries('REPLACE');
var resolution = time.Duration.parse('PT15M');
for (i=0; i < 4; i++) {
  var zdt = rounded.plus(resolution.multipliedBy(i));
  var value = "0";
  ts.add(zdt, value);
}

// Write the control points to the database.
var controlItem = items.getItem("HeatPumpCompressorControl");
controlItem.persistence.persist(ts);