Spot Price Optimizer: Advanced algorhitms to optimize heating, charging of electric vehicles, water boilers and more

You are on the right tracks with your investigations. The reason why the current version has this filter is that the way the prices are fetched using entsoe.js and then saved with influx.js is completely bypassing the openHAB persistence layer when it is saving the spot prices to the influx database.

At some point I wanted to see the spot price for the currently ongoing hour on my openHAB main screen and to achieve that, I had to have an hourly rule which reads the value from the influx database and updates the Item. But when this was done, openHAB registered the Item state change and persisted that again to the database, leading to double entries. So I added that filter to get only the values which were originally fetched with entsoe.js.

As I mentioned in my previous post, I’m currently working towards version 4 where this optimizer would only focus to the optimization algorithms and would rely on Bindings to fetch and persist the price and weather forecast data as a proper timeseries now that openHAB supports it. But this work will still take some time. I’m doing this as a hobby project when I happen to have time. I’m a semi-professional athlete and we have the World Mixed Doubles Qualification Event in 2.5 weeks from now where there are spots to the Olympic Qualification (and World Championships) at stake, so I’m focusing on the preparations on this all-important competition at the moment.

What comes to your own customized logic to support the tibber prices, I would recommend to print the debug information to the logs and see what you have over there. So before you pass the pricesnew to the GenericOptimizer, have a look at what you have there. You can do that by

console.log(JSON.stringify(pricesnew);

Cheers,
Markus

Hi Markus,

may I ask/suggest to make the optimizer more flexible wrt the inputs? I already have the spot prices in a timeseries which I’d like to use here. Also for any weather information I do have items already. Maybe you can offer to use those items, just like the “Weather Calculations” binding(?).

Thanks!

Hi, that’s exactly the plan on the roadmap for 4.0 version of this (see the opening post and my previous comment).

Markus

Version 3.0.3 published at npm. In Finland the the spot prices for the last 4 hours are the same for tomorrow Nov 16 (and the 00-01 of Nov 17). The last hours where the price is equal were not handled properly and are missing with version 3.0.2 and earlier.

Changelog from 3.0.2 to 3.0.3

  • Bugfix: EntsoE API response with A03 type will not explicitly indicate the last hours of the day if the price doesn’t change. Fix the response parsing to handle this situation correctly.

Update instructions:

This sounds pretty much exactly what I would like to see. In other words, a very different kind of a house compared to ours, which has 375 mm thick siporex walls and quite high capacity to preserve the thermal energy (U = 0.2 W/m2K).

I would be interested in this kind of data:

  • Green line is the indoor temperature
  • Red line is actual outdoor temperature
  • Pink area is when the control points for heating has been 1

The code for the chart page is as follows:

config:
  label: Lämpötilaseuranta
  order: "-10"
  period: 2D
  sidebar: true
slots:
  dataZoom:
    - component: oh-chart-datazoom
      config:
        height: "100"
        orient: horizontal
        show: true
        type: slider
  grid:
    - component: oh-chart-grid
      config: {}
  legend:
    - component: oh-chart-legend
      config:
        orient: horizontal
        show: true
  series:
    - component: oh-time-series
      config:
        gridIndex: 0
        item: TempOH
        markLine:
          data:
            - label:
                distance: -150
              name: Avg
              type: average
        name: Sisälämpötila (OH)
        service: influxdb
        type: line
        xAxisIndex: 0
        yAxisIndex: 1
    - component: oh-time-series
      config:
        gridIndex: 0
        item: ValloxMVTemperatureOutside
        markLine:
          data:
            - label:
                distance: -150
              name: Avg
              type: average
        name: Ulkolämpötila
        type: line
        xAxisIndex: 0
        yAxisIndex: 1
    - component: oh-time-series
      config:
        areaStyle:
          color: "#f3b4b4"
          opacity: "0.5"
        gridIndex: 0
        item: nibe_control
        itemStyle:
          color: "#c23531"
        lineStyle:
          opacity: 0
        name: Lämmitystunnit
        step: end
        type: line
        xAxisIndex: 0
        yAxisIndex: 2
  tooltip:
    - component: oh-chart-tooltip
      config:
        confine: true
        orient: horizontal
        show: true
  xAxis:
    - component: oh-time-axis
      config:
        gridIndex: 0
  yAxis:
    - component: oh-value-axis
      config:
        gridIndex: 0
        name: Sisälämpötila
        nameLocation: center
    - component: oh-value-axis
      config:
        gridIndex: 0
        name: Ulkolämpötila
        nameGap: 40
        nameLocation: center
        splitLine:
          show: false
    - component: oh-value-axis
      config:
        gridIndex: 0
        show: false
        splitLine:
          show: false
    - component: oh-value-axis
      config:
        gridIndex: 0
        show: false

Hello,

I was wondering why the FMI data ends at 23:00 and not 24:00 on my chart?

BR, Jakke

Because you’re using version earlier than 3.0.3 which I released yesterday.See two comments above.

Edit: Now I realized that you were talking about FMI data and not price data. Disregard my comment above.

At least in my graphs the weather forecast line ends every day at 23.00, because that’s the last point of today. The forecast point for 00.00 is visible on tomorrow’s chart for me. Do you see it there? If not, re-run your rule that fetches the weather forecast and check the log output if you still don’t see the weather forecast data.

Cheers,
Markus

Hello,

Yes the point is visible in the next day’s graph. Sorry for the unnecessary noise. I just somehow expected to see a continuous line on the chart between 23:00 - 00.00.

BR, Jakke

I found out the hard way that the script can not handle local characters in the influx organization name.

A small check in the writePoints function could have helped finding out the issue.
Maybe something like:
var response = http.sendHttpPostRequest(url, ‘application/json’, data, headers, 5000);
if (!response.length === 0 ) {
console.debug( ‘influx.js:’ + response );
}

Hi will this version have functions for summer/wintertime for different timezones, I’m still on version 1 I think. So I am off by one hour, even thoug it seems like two hours off on the graph.

Current version has no issues handling daylight saving time properly.

Great to know, I just need to figure out how to set start and stoptimes from datetime item for my EV charger to check for x amount of hours from evconnected datetime to evFinsihedTarget datetime, I had it working on my old rule but a isshappening of deleteing my old rule before all was converted from version 1 to version 3.

I also used to have a specific logic for default value, so in old scripts I have changed defaulting to 1 to defaulting to 2, in that simple way I had a failsafe on wath to do when no data was received. This script seems to have better solutions for it.

You can read the datetime Item to a variable and then convert it to a ZonedDateTime object like this (change the name of the Item obviously to match what you have):

var item = items.getItem("CarChargingLatestEnd");
var latestEnd = time.toZDT(item.state);

Markus

Hi

Yes i figured that one ou yesterday night and I did put in some new configuration of the rules, as I even did for all rules I have seven different items runnig on this script. Where I added a section for configuring measurment name in influx, control item output item and function name si could massproduce rules easier.

// import start and stop times from items
var startItem = items.getItem("Evconnected");
var start = time.toZDT(startItem);
console.log(start);
var stopItem = items.getItem("EvCarReady")
var stop = time.toZDT(stopItem);

Next issue to handle will be a conversion of price just for the estetics of the chart, I will try to convert prices to SEK/Kwh where I have an item that holds a valid exchangerate for EUR to SEK, no fun reading for the moment.

You can store the prices in SEK. Use the multiplier that is used to multiple the raw price with VAT multiplier. See here:

Markus

made a working solution, it will nevere win any beaty contest but works. The 0.117 is my electric companys margin.

in entsoe.js I modified tax calculation part and in rule I have exchangerate conversions.

// Loop through spot prices. Convert EUR / MWh to c / kWh and add tax.
    for (let i = 0; i < normalizedPoints.length; i++) {
      let current = start.plus(resolution.multipliedBy(i));
      let datetime = current.format(time.DateTimeFormatter.ISO_INSTANT);
      let price = ((normalizedPoints[i]['price.amount'] * tax)+0.117)*1.25;

rule modification

// Multiplier for VAT. Adjust this to your country or leave as 1.0.
var exchangerateItem = items.getItem("ExchangerateEuro");
var exchangeratefactor = (exchangerateItem.state/1000);
var vat = exchangeratefactor; 

I will try to see if I can understand how to pass new parameters to entsoe.js containing exchange rate and marging before adding taxes.

your code goes here

I’m almost done on the beta version of version 4.x which relies on real Bindings to fetch price and weather forecast data as long as those bindings persist the prices and weather forecasts as real timeseries.

I would appreciate help in beta testing the new version and especially the cutover from the current 3.x to 4.x in a situation were previous price and control point data exists in the database.

I explicitly don’t want anyone testing the beta version in their PROD environment which controls real world devices. So do we have any community members here that would like to help with testing and

  • either already have a development / test environment
  • or have the skills to spin up a test environment?

I can share my own docker setup and give brief instructions on how to copy an influxDB from one environment to another but I would prefer to spend my time on developing this new version rather than helping to troubleshoot other people’s test environment setup. So previous experience on this kind of environment setup would be preferred.

Cheers,
Markus

I don’t recommend to spend too much time on that if you already figured out a solution that works. The next major version 4.x will not have entsoe.js at all, it will rely on the new version of EntsoE binding which will be part of the openHAB 4.3.0 (it’s included in 4.3.0 Milestone 4 build which was released two weeks ago).

The EntsoE binding will convert the spot prices to SEK for you if I’m not completely mistaken. And then you can use a Channel Transformation to add your margin and taxes if they are flat rate (i.e. same regardless of the time of day).

If you want to add grid tariff which varies on the time of day, you can use the TariffCalculator included in this module (documentation is available in the wiki). If the current methods (night distribution and seasonal distribution) are not matching to the pricing logic of your grid provider, you can request a new feature by providing the pricing logic details of your grid provider.

Markus

HI

Thanks for the tio, I’m just a little restrictive with upgrading OH version I let more experienced users figure out some issues first. But it will be really good when it happends. I hope one can use a grafana chart for that spotprices and which ever controls I would like, beacuase I like grafana charts.

Hi all, has anyone had problems with InfluxDB2 persistence services? I installed the 3.0.0 version and Rules FetchSpotPrices and FetchWeatherForecast work both fine and the Data Explorer and Grafana as well print a nice graph of all relevant measurements, but once I create the first rule for the new Optimizer, save and push the run-button, the log goes wild and gives constant errors, claiming “no route to host, database not ready” and various errors referring to connection problems, like:

java.net.NoRouteToHostException: No route to host
at sun.nio.ch.Net.pollConnect(Native Method) ~[?:?]
at sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[?:?]
at sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:549) ~[?:?]
at sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597) ~[?:?]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[?:?]
at java.net.Socket.connect(Socket.java:633) ~[?:?]
at okhttp3.internal.platform.Platform.connectSocket(Platform.kt:128) ~[?:?]
at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.kt:295) ~[?:?]
at okhttp3.internal.connection.RealConnection

My Openhab server on Raspberry Pi 4 is located in our basement (cellar) and part of the connection jumps over WiFi-repeater, could that be the problem with this much more sophisticated new system, although those two main rules work just fine, like everything did before this system update? InfluxDB2 runs on a desktop upstairs.

  • Risto