Show future total spotprice/totalprice in a chart

Im lost here and therefore need some help/advice. (sorry for the long post).
As this is mainly regarding the Energi Data Service from @laursen he could come in hand.

Problem:
I want to show a chart on my page (dashboard, created in MainUI) for future upcoming prices (totalPrise). Atm I have the current totalprice showen. And when I click on it, it shows the build-in chart of the daily history. This is basicly my knowlegde in openHAB.
But I would like to show the furture price.

I have read the description of Energi Data Service binding aprox a zillion times. This feature is mentioned, but I simply dont get it. I have no idea where to start, whats required and whats not required to do this. I know that Energi Data Service binding do collect the future prices. I just dont seem to understand, how to get those data to a chart. Or if it even do collect the data by default.

I use the default items setup from the binding: (items file).

Group:Number:EnergyPrice:SUM TotalPrice "Total Price [%.2f kr]" <price>

Number:EnergyPrice SpotPrice                "Spot Price"                <price> (TotalPrice)                                        { channel="energidataservice:service:9cb682c5e9:electricity#spot-price" [profile="transform:VAT"] }
Number:EnergyPrice GridTariff               "Grid Tariff"               <price> (TotalPrice)                                        { channel="energidataservice:service:9cb682c5e9:electricity#grid-tariff" [profile="transform:VAT"] }
Number:EnergyPrice SystemTariff             "System Tariff"             <price> (TotalPrice)                                        { channel="energidataservice:service:9cb682c5e9:electricity#system-tariff" [profile="transform:VAT"] }
Number:EnergyPrice TransmissionGridTariff   "Transmission Grid Tariff"  <price> (TotalPrice)                                        { channel="energidataservice:service:9cb682c5e9:electricity#transmission-grid-tariff" [profile="transform:VAT"] }
Number:EnergyPrice ElectricityTax           "Electricity Tax"           <price>                                                     { channel="energidataservice:service:9cb682c5e9:electricity#reduced-electricity-tax" [profile="transform:VAT"] }

I run a standard openhabian setup with openHAB 5.1 which uses Rrd4j database.
I did try install the inMemory, as suggested in the binding description, but it gave me some other problems, and never actually helped me in my lack of understading, how to get the data from the binding into the chart. So I switched back to use Rrd4j as the default. I have no idea if it will work or not.

Status right now:
I have the binding running, it collected current data, and I think it collects furture data as well (im not sure though). I have the rule running to update for future data, I think. Simply by copying the rule from the binding description (JavaScript) for the time series. I do wonder though, how its triggered as there is no trigger in the rule. Its unclear to me, if this is triggered automactily from the binding when “DAY-AHEAD-AVAILABLE” is “available”.
Rule:

rules.when()
    .channel('energidataservice:service:energidataservice:electricity#event').triggered('DAY_AHEAD_AVAILABLE')
    .then(event => {
        // Short delay because persistence is asynchronous.
        setTimeout(() => {
            var timeSeries = new items.TimeSeries('REPLACE');
            var start = time.LocalDate.now().atStartOfDay().atZone(time.ZoneId.systemDefault());
            var spotPrices = items.SpotPrice.persistence.getAllStatesBetween(start, start.plusDays(2));
            for (var spotPrice of spotPrices) {
                var totalPrice = spotPrice.quantityState
                    .add(items.GridTariff.persistence.persistedState(spotPrice.timestamp).quantityState)
                    .add(items.SystemTariff.persistence.persistedState(spotPrice.timestamp).quantityState)
                    .add(items.TransmissionGridTariff.persistence.persistedState(spotPrice.timestamp).quantityState)
                    .add(items.ElectricityTax.persistence.persistedState(spotPrice.timestamp).quantityState);

                timeSeries.add(spotPrice.timestamp, totalPrice);
            }
            items.TotalPrice.persistence.persist(timeSeries);
        }, 5000);
    })
    .build("Calculate total price");

If I have this figured corectly. Then - Whats next? How do I get this into a chart?

I would be greatfull if anyone can help with a step by step process to archive this task.
Please keep it as simple as possible. This will have to be a learning curve to me, as I intend to extend this to more complex use of the future price. (like having the washingmachine start a the lowest price, etc). So I need to understand/learn, rather than just be given the solution, and still not having a clue whats going on :slight_smile:

Thanks in advance.

Quite awhile back persistence was modified to support saving future states for items. But rrd4i doesn’t work that way and there really is no purpose in saving future states to disk. So any binding that provides forecast data will recommend using the In Memory persistence service instead.

To use it you need to install the add-on of course.

Next you need to set the persistence config. Go to MainUI → Persistence → In Memory under Configure Strategies. Select the Item(s) that the binding provides future forecast states to and choose “forecast” as the strategy.

That’s it. Now the future forecast data will be available to charts and in rules and such. You just need to set the time period for the charts to the future and for chats and rules you need to select the in memory persistence to query instead of rrd4j.

Yes there is.

That’s the trigger.

That’s my interpretation of the trigger.

Thanks alot Rich.

As I do understand most part of the persistens service, and do have inmemory installed. I did gave it up again, cause when looking at the configuration for Rrd4j, it seems like its deafult set to wildcard ‘*’ and therefore persists all items. I was unsure if I would have to disable Rrd4j and only use inmemory, or if I can use both at the same time, without having to specify all items individually ofcouse.

As for the setup of inmemory, the binding documents have this filebased example:

Strategies {
    default = everyChange
}

Items {
    SpotPrice,
    GridTariff,
    SystemTariff,
    TransmissionGridTariff,
    ElectricityTax: strategy = forecast
}

First I noticed (the hard way) OH 5.1 had changed, (after reading the docs for persistens). The default strategy no longer works. It now has to specify strategy for each items/group etc. So I deleted that line. But even though I had the file named inmemory.persist, the log said there is a configuration error.. thats why I gave it up.

According to the example, only the ElectricityTax is suppose to have the strategy of forecast. Im not sure why though, Makes no sense to me, as its part of the total price (the group item totalPrice). So I was a bit unsure how to have different strategy for these items in the same configuration using MainUI setup.. But maybe I just need to add another configuration in MainUI?

I did tried the filebased configuration though like this:

Strategies {
   // default = everyChange
}

Items {
    SpotPrice, GridTariff, SystemTariff, TransmissionGridTariff : strategy = everyChange
    ElectricityTax : strategy = forecast
}

But it gave me the above mentioned error configuration.

Now, this is where it get abit complicated to me..
I dont see where to specify/select inmemory in the action (analyse) of a labelcard or any other card.
Second, I have no idea which items to use query either for the future data beeing analysed/charted?
Maybe I got this all wrong?

EDIT:
This is weird. I dont know if its suppose to do this or if it happens because I run the rule manually for testing purpose.
Everytime I run the “Calculation future total price”, then this rule creates a new rule named “Calculate total price”, without deleting the previous.
See screendump:

They´re locked, so I cant delete them.
But maybe this is suppose to happen?
The “Calculation of future total price” rle is the action JavaScript mentioned in the first post.

You can use both at the same time. You can have as many persistence services installed and configured as you want. Nothing you do to the In Memory config will change anything about rrd4j.

I’m sure there are lots of places in the doc that have examples that need updating.

Without the error :person_shrugging:

I know nothing about this add-on so can’t help with that. The binding controls what Channels support forecast and which ones don’t. You have no control over that.

The only configuration needed is listing the Items that are supplied with a forecast and the strategy forecast in the In Memory persistence config.

MainUI → Settings → Pages → Add Chart

Fill in the properties.

Add a Grid.

Add a timeseries to the Grid.

Click the black icon to configure the timeseries. Click “Show advanced”.

That’s going to be in the binding docs. I don’t know this binding so :person_shrugging: .

That’s weird. How are you running the rule manually? Is the entire contents of the file what you posted above? Or did you paste that JS code into a UI rule? If the latter, this is expected behavior because your UI rule is just creating a new rul;e every time it runs. That code above must be put in a .js file in $OH_CONF/automation/js same as any file based rule.

1 Like

Great. Thats what I hoped for.

It just said missing configuration. There were no configuration when I looked from MainUI. So it was right. However I had the above persistens configuration as a file.

I have now added a configuration within MainUI insted. And the error is gone.

Ahhh, that was it!

I was trying to use a layout page with a widget/card and then the analyse setup.
I understand now, I have to create a new actual chart page.
Thanks, now it makes alot more sense :slight_smile:

The binding doc said “In this example file-based using Rule Builder:”
I search the docs, cause I knew nothing about this Rule Builder. As far as I understood, MainUI is the Rule Builder. So I assumed the actual rule was supposed to be copied directly in as “execute an inline script”. At least thats how I understood the Rule Builder. I seem to have misunderstood this. From MainUI I could run it manually.

My DSL file based rules are located in the $OH_CONF/rules/ :slight_smile:

Anyway..
I have now moved the rule from MainUI to $OH_CONF/automation/js
This is the log output.

2026-01-25 22:27:31.051 [INFO ] [ort.loader.AbstractScriptFileWatcher] - (Re-)Loading script '/etc/openhab/automation/js/future total prices.js'
2026-01-25 22:27:32.632 [INFO ] [.openhab.automation.openhab-js.rules] - Adding rule: Calculate total price

It seems like it has removed the other three weird rules in the scrrendump above, yet it did created a new one. I guess thats the purpose then.

Hopefully this part works now.
Then I can focus on getting the chart created tomorrow. (Its almost midnight now here in Denmark).

Thanks for all your help, sofar, Rich.

No. It says right there it’s file based.

What you’ve done is creates a rule that creates a rule in the UI. So of course, every time you run it, a new rule appears.

But this isn’t Rules DSL.

The JavaScript Scripting automation add-on will load .js scripts from automation/js in the user configuration directory.

I know. It was suppose to be a joke, cause you previously wrote:

Sorry you misunderstood. That wasnt my intention.

Anyway..
I have now spend the last few hours trying to get this to work. I created a chartpage, but the outcome looks like the persistens doesnt work.

I have no idea which item to query, (I assume its ‘totalprice’). But it just show a static value in the time-series. The binding doc isnt clear on this part, or how to get from the first javascript to the second rule, (which the javascript creates).
It seems to me the binding doc assume I already know something, which I dont. Or I dont get it..
Seems like Im stuck :frowning:

Is the rule triggering?

Again, I know nothing of this binding but I see several relevant things in the docs.

Manually Persisting History

During extended service interruptions, data unavailability, or openHAB downtime, historic prices may be absent from persistence. A console command is provided to fill gaps: energidataservice update [SpotPrice|GridTariff|SystemTariff|TransmissionGridTariff|ElectricityTax|ReducedElectricitytax] <StartDate> [<EndDate>].

Example:

energidataservice update spotprice 2024-04-12 2024-04-14

This tells me:

  1. The binding only pulls the forecast data periodically and no during OH startup. If you miss the schedule you miss the data, but you can run a command to have the binding go and retrieve the latest forecast on demand.
  2. SpotPrice, GridTariff, SystemTariff|, TransmissionGridTariff, ElectricityTax,ReducedElectricitytax are the Channels that provide forecast data.

The list in 2 matches the list of Items shown in the example .persist file in the docs and posted above.

The rule to calculate the total price is never going to work if the other Items are not being populated. So focus on those first.

Beyond that I can’t really help.

It does if I force it to manually “restart” (ie rename the rule file to .old and then back to .js again).
But I cant see if it update the item with future data.

I tried the Manual persisting History command as well. Still the same result.

I know. Thanks for your help anyway.
I´ll have to wait untill @laursen have time to respond.

That won’t trigger the rule to run. That will just remove and readd the rule. The Binding needs to publish the ‘DAY_AHEAD_AVAILABLE’ event on the energidataservice:service:energidataservice:electricity#event Channel to cause the rule to run.

I’d guess there’s nothing for this rule to do until that event is published. And if that event isn’t being published, none of the Items have their forecast data.

It’s super easy to see if a rule ran. Add a log statement and watch/search the logs.

But if the Items are not being updated, the rule isn’t going to work .So focus on that and forget the rule. Only when all the Items are generating charts worry about the rule.

Based on the docs, running that command from the karaf console will probably cause the event to be published and the rule to run.

Thats what i´m trying to focus on. But since i´m not sure exactly how this is suppose to work for future data, while not beeing able to see, if the items persist future data or not. Its kinda hard.

I know for sure the items do update for the current data. So I know the binding it running.

I think I have found a setup mistake though. I had the item ‘totalprice’ setup up as a group item, which update each time spotprice update, (it updates aprox every 15 minutes). I think it overwrites the group item. But im not sure, cause I have no idea how the furture data is beeing written to an item. But for my understanding, it seem wrong to define ‘totalprice’ as a group item.

I have now definded the ‘totalprice’ as an individual item. This is what the logfile showed when I saved my items file:

==> /var/log/openhab/openhab.log <==
2026-01-27 11:21:02.000 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading DSL model 'EnergiDataService.items'
==> /var/log/openhab/events.log <==
2026-01-27 11:21:02.115 [INFO ] [openhab.event.ItemUpdatedEvent      ] - Item 'TotalPrice' has been updated.
2026-01-27 11:21:02.418 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'TotalPrice' changed from NULL to 2.05932105875 DEF/kWh (source: org.openhab.core.persistence)

To me it looks like it went from Null to the persisted data insted.

The chart still shows the static value 2.06 afterwards.

But from the log, I would say next step might be to get the rule to run, or wait untill aprox 13.00 o’clock today, where it should update itself.

You need to solve the persistence topic, otherwise working on the rule or chart will not succeed.

Establish a clean state

  • install inmemory persistence
  • remove your text config inmemory.persist
  • just to be sure: the items from top post are properly connected to enegridataservice thing?

Persistence config

  • use the UI, not text config, at least for now
  • go to Adminstration - Settings - Persistence and select from Configure Persistence Policies - In Memory (picture 1)
  • you can remove existing policies if you wish
  • Add a new configuration and add your items from top post (picture 2)
  • don’t forget to save

From now on the updates are stored in memory. But the price bindings are updating only once per day!
To force an update disable energidataservice thing and enable it again.

Graph

  • ensure the items showed in the graph are getting the data from the right persistence (picture 3)

Pic 1

Pic 2

Pic 3

1 Like
  • done
  • done
  • done

This is my items file for EnergiDataService:

Number:EnergyPrice TotalPrice "Total Price [%.2f kr]" <price>

Number:EnergyPrice SpotPrice                "Spot Price"                <price> (TotalPrice)                                        { channel="energidataservice:service:9cb682c5e9:electricity#spot-price" [profile="transform:VAT"] }
Number:EnergyPrice GridTariff               "Grid Tariff"               <price> (TotalPrice)                                        { channel="energidataservice:service:9cb682c5e9:electricity#grid-tariff" [profile="transform:VAT"] }
Number:EnergyPrice SystemTariff             "System Tariff"             <price> (TotalPrice)                                        { channel="energidataservice:service:9cb682c5e9:electricity#system-tariff" [profile="transform:VAT"] }
Number:EnergyPrice TransmissionGridTariff   "Transmission Grid Tariff"  <price> (TotalPrice)                                        { channel="energidataservice:service:9cb682c5e9:electricity#transmission-grid-tariff" [profile="transform:VAT"] }
Number:EnergyPrice ElectricityTax           "Electricity Tax"           <price>                                                     { channel="energidataservice:service:9cb682c5e9:electricity#reduced-electricity-tax" [profile="transform:VAT"] }

Notice the first. Thats the item I use for the chart. I believe thats the items which the rule will used for fetching the furture data. Is that correct?

I have removed it as a Group, as I was uncertain if it would “delete” the persisted data, just to make sure. I still havnt figured this, and it dont seem to make any difference in the chart.

  • done
  • done
  • done
  • done
  • done

This is the inmemory configuration:

configurations:
  - items:
      - ElectricityTax
      - GridTariff
      - SpotPrice
      - SystemTariff
      - TotalPrice
      - TransmissionGridTariff
    strategies:
      - forecast
    filters: []
aliases: {}
cronStrategies:
  - name: everyMinute
    cronExpression: 0 * * ? * *
  - name: everyHour
    cronExpression: 0 0 * * * ?
  - name: everyDay
    cronExpression: 0 0 0 * * ?
thresholdFilters: []
timeFilters: []
equalsFilters: []
includeFilters: []

I tried disable/enable the binding. All EnergiDataService items updates, except the ‘TotalPrice’.

Exactly which item is suppose to be entered in Pic 3 ??
EnergiDataService got 5 items, ‘Spotprice’, ‘GridTariff’, ‘SystemTariff’, ‘TransmissionTariff’ and ‘ElectricityTax’.
Beside that it got this ‘TotalPrice’ which is a sum of the 5 items. Which I believe is beeing updated through the rule?

’TotalPrice’ is the one I want to chart. So thats the item I have added in the chart setup (time-series) as well as specified inmemory persistens.

This is my chart/time-series setup:

onfig:
  label: Future elpris
  future: 1
  period: 12h
slots:
  grid:
    - component: oh-chart-grid
      config:
        show: true
  xAxis:
    - component: oh-time-axis
      config:
        gridIndex: 0
        name: Tid
  yAxis:
    - component: oh-value-axis
      config:
        gridIndex: 0
        name: Kr
        min: "0"
        max: "7"
  series:
    - component: oh-time-series
      config:
        name: Series 1
        gridIndex: 0
        xAxisIndex: 0
        yAxisIndex: 0
        type: bar
        item: TotalPrice
        service: inmemory
        markers:
          - avg
  visualMap: []

Am I doing this wrong?

This is the outcome, when I press the Run button in the chart page setup:

Its starting to get rather frustrating when any changes doesn seems to matter..

ARRRGH (sorry, some more frustration).

I just tried exchange the ‘TotalPrice’ in the time-series setup to use ‘SpotPrice’ insted. Thats all I did change. This is the outcome:

Now, this tells me item ‘SpotPrice’ is beeing persisted just fine, and the chart is working.
Im back to the item ‘TotalPrice’ which for some reason do not work.

Don’t get frustrated :slight_smile: You’re too fast and looking too much to the wanted result.
You successfully mastered to show the future values of the SpotPrice in the graph.
This is good!

All of them needs to be configured in inmemory persistence. This is 100% needed as pre-condition for your calculation!

Add all of them into the graph and all of them need to have proper values.
If this is done we can continue checking the rule!

What about the item totalPrice ?

Im lost here..

  • How do I add more than one item to the chart time-series?

  • And why?

I thought the binding rule would calculate each items and then write it to the totalPrice isnt that the purpose of the rule?
(If not, I have failed to understand this for sure, which may explain my frustration for sure).

Ok, let’s try to sort this out. Apoligize in beforehand for being nit picky :slight_smile:

  • the rule has nothing to do with the energidataservice binding. I mean literally nothing. Yes, it’s an example from the documentation how to calculate the total price but it’s not technically related to the binding.
  • the energidataservice binding only provides values which are forwarded to the items and then stored in the persistence
  • as rich explained rrd4j cannot store future values, that’s why inmemory persitence is needed and each item needs to connected to this persistence
  • the rule if you look a bit closer is just operating on items and add them up

Basically
binding –provides values–> item --storage in-> inmemory persistence
rule –using–> item –reading values–> from inmemory persistence

The graph is useful if the above configuration is correct!
The sum in the rule is the final step after the the above configuration is straight. It will not work without this config!

You already have a graph as shown above in your screenshot. Just scroll down in the and Add Time Series. Pick the item to display plus the Persistence service where the data shall be fetched from.

So I should add a time-series for each item?

Yes, so @weymann can verify that all your Items are configured correctly and are working with the binding. Once that’s confirmed you can start working on the rule to calculate the states for the totalCost Item.