Tibber [OH5]


CAUTION - CAUTION - CAUTION

Tibber binding is already released in openHAB. Several stability issues are reported which are bugging me a lot. There are also flaws e.g. spot-prices are updated every minute which causes 1440 queries per day. Additionally channels are a boquet mixture of spot-prices, live measures and statistics.

I want to start a proposal for OH5 which can introduce some breaking changes. On Marketplacce I’ll a publish a compatible version which shall solve stability errors.
This is now a rework of the previous binding - all channels renamed, units like Currency and EnergyPrice added, ThingActions for price calculations added.
Highly recommended to check readme for changes.

Changelog

Version 0.2-alpha

  • Channels rework
    • price group
      • spot-prices current and forecast prices as Number:EnergyPrice
      • level current and forecast price levels as Number with 0=Normal, negative values cheaper, positve values expensive
      • average current and forecast of 24h average prices as Number:EnergyPrice
    • live group for Tibber Pulse power, voltage and current values
    • statistics group for Tibber Pulse energy values
  • ThingActions added for price calculations
    • priceInfoStart - earliest price info available
    • priceInfoEnd - latest price info available
    • listPrices - retreive list in ascending / descending order of prices
    • bestPricePeriod - calculate best rpice in consecutive period
    • bestPriceSchedule - calculate best rpice as non consecutive schedule

Version 0.1-earlybird

  • no channel changes
  • usage of jetty http common client to avoid SSL trust certificate errors
  • avoid spot price updated every minute
  • cron based updates instead of refresh intervall

Resources

Bundle
org.openhab.binding.tibber-4.3.6-SNAPSHOT.jar

Source Code

3 Likes

Rationale
I just wanted to fix the stability issue reported in the forum. Looking a bit deeper there are several topics which needs to be improved.

Configuration
Config refreshInterval isn’t necessary
Spot prices are udpated once per day and the binding shall evaluate at which hour this update occus instead of polling each minute!
This can be solved without changing cahnnels.

Channels
The current channels are a mixture of spot-prices, live-updates and statistics. My goal for OH5 (where we can introduce some breaking changes!) would be to structure the channels into groups to have some ordering.

Please share your thoughts!

2 Likes

I did propose some time ago a kind of “merge” or at least some kind of combination of “dynamic pricing” things. I know, technically the APIs of e.g. Tibber and aWATTar are way different, but so are PV forecasts also, and we have two of them in one binding! :wink:

so, I’m not really sure, if this is feasible or not, but perhaps worth a look (the discussion soon went off-rails, but nevertheless):

In the mean time I myself wrote a bunch of rules to manage at least my requirements of letting my wallbox, (pool)heater, disher, … consume, when energy is cheap.

other than that, my thoughts are also having a stable Tibber binding for all kinds of information available from the Tibber API - plus the 15min strategy the spot market will introduce also for end user now in October, so my wishlist is:

  • stable prices, which correctly change according to the model at exactly on the hour or on 15mins
  • live consumption with websocket part of the API
  • statistics maybe configurable on minute basis?

optional:

  • some kind of pre-build “low price hours” or “high price hours” functionality, which is configurable on the current gross price and in best case is also a configurable time series. So, you type in your intervals (e.g. < 15ct, <25ct, <35ct, >35ct) and get a time series with those intervals to plan your future consumption on that?
    (yes, there’s the current_level channel, but let’s be honest, the Tibber logic is not sufficient for a real smarthome?)
  • or like aWATTar you are able to add some kind of things, which calculate the best time for consumption for that device. But in best case also here I can change the variables for that device, so e.g. based on current SoC or whatever you can chose the period of consumption dynamically. In aWATTar, I have to configure daily static length of consumption and the thing calculates with this static inputs. I’d like to have the calculation dynamically.

Thing is, all those “optional” requirements are kinda fluent and may differ from one smarthome to another? e.g. with my, as I have both PV forecast and Tibber prices to calculate with and come up with the best way to postpone consumptions based on both PV and grid prices…

Took a bit longer than I thought with all the channel rework, examples and actions I added. As mentioned in the top post
CAUTION - CAUTION -CAUTION
This is now a complete reworked binding - not approved but Pull Request is raised"

  • Channels rework
    • price group
      • spot-prices current and forecast prices as Number:EnergyPrice
      • level current and forecast price levels as Number with 0=Normal, negative values cheaper, positve values expensive
      • average current and forecast of 24h average prices as Number:EnergyPrice
    • live group for Tibber Pulse power, voltage and current values
    • statistics group for Tibber Pulse energy values
  • ThingActions added for price calculations
    • priceInfoStart - earliest price info available
    • priceInfoEnd - latest price info available
    • listPrices - retreive list in ascending / descending order of prices
    • bestPricePeriod - calculate best rpice in consecutive period
    • bestPriceSchedule - calculate best rpice as non consecutive schedule
1 Like

I installed the tibberOH5 binding from the marketplace in my test-environmen (OH5-Milestone in docker). Runs since two days now, and no updates on the items yet.
I guess, it was v0.1-earlybird. Do I have to do anything to upgrade to yesterdays 0.2-alpha?

ok, scratch that. I just removed the tibber core-binding with beforehand “unlink and remove items”, and all my Tibber OH5-items were also gone. I guess both bindings in parallel won’t work! I then removed your oh5-binding and re-installed it. I’ll keep watching what’s happening.

Correct, they won’t work in parallel. And the current Marketplace version is now a rework of current Tibber binding as mentioned in the top post. It’s structured now into price group which doesnt require a Tibber Pulse hardware. Groups live and statistics can be connected if you have a Tibber Pulse.

Also be aware that all price items are now TimeSeries! spot-price, level and average items are not compatible with default rrd4j persistence. They need to be stored e.g. into inmemory or influxdb. Otherwise they will stay null!

2 Likes

yes, I did get that. I set the standard persistence to jdbc/mariaDB.

But, what I see is some kind of jitter or whatnot? Future values should be drawn correctly, but past values kinda fall back an hour or two?


future prices are ok:

any idea, what’s causing this? I did activate the item today at around 15:15h, so since 16h the timeseries changed hourly.

1 Like

Indeed that’s curious. Cannot tell you which value of the zick-zacks is showing the real value. I’m running this now for 2 weeks but without running offiicial Tibber binding before.

But this is exaclty one point why I decided to do a rework.

  1. For TimeSeries current Tibber implementation converts price start Instant timestamp to ZonedDateTime without respecting time zone (this is dangerous!) and then back to Instant again!?!?

  2. In addition current Tibber implementation updates the current-total price with frequent polling. I mean the rpices are given at the updateHour as TimeSeries, why overwrite them?

  1. Minor point but important for the item unit: now prices are delivered as EnergyPrice with the correct unit - for me EUR/kWh

tl;dr
Please check the next days if the openHAB price fits to the Tibber price shown in the app. For me they do! I tested it with a small rule

rule "Tibber Price Change"
when
    Item Tibber_API_Spot_Price received update
then
        logInfo("TibberPriceChange","Price changed to " + Tibber_API_Spot_Price.state.toString+ " at " + ZonedDateTime.now.toString)
end

of course I agree with you, that after known prices (at around 13h) you should only poll that info once, there will be no change afterwards.

Then the item units and everything were used from the binding, I used “add equipment to model” and just “select all”. :wink:
so, the currentPrice is sent to this item:

label: Spot Prices
type: Number:EnergyPrice
icon: ""
groupNames:
  - Tibber
tags:
  - Point

unit: DEF/kWh
State description pattern: %.3f %unit%

I will keep a look at it, but still:

What could be is that the timing is a bit too early? Which means something thinks its already after the hour, while another thinks its still on the hour?
Meaning, the timeseries are out-of-sync with the hour change. I did not have that issue with the core-item? Did you change something regarding to dates?

My host hat TZ: Europe/Berlin as does my docker-compose tell the container to use and what I configured the openHAB to use…?

That’s so true and I’m absolutely agreeing with you! That’s why the first call of creating a Tibber thing before you’re connectiong items is checking the currency. If you enable TRACE level you should see a trace

2025-05-31 18:12:02.102 [TRACE] [ibber.internal.handler.TibberHandler] - Currency is set to €

otherwise something like

Currency {} is unknown, falling back to DecimalType

If you don’t see either of these traces you’re really on the earlybird version. You can disbale and enable thing to check the traces but if you don’t see them I would recommend to update to latest Marketplace version. Stabilizing the current implementation is not the right direction!

Can you extract the extact timestamp from your mariaDB when which value is stored?

With the oh5-binding I don’t have the settings/configuration icon, where I could change log-level for the binding. Perhaps that’s something to add here?

319 │ Active │ 80 │ 4.3.6.202505291447 │ openHAB Add-ons :: Bundles :: Tibber Binding should be the 0.2-alpha I guess judging from the timestamp in there! :wink:

so, FWIW here’s the spot price since yesterday:

the timestamps in my mariaDB:

Spot Price
2025-06-01 23:00:00.000	0.2707
2025-06-01 22:00:00.000	0.2891
2025-06-01 21:00:00.000	0.2902
2025-06-01 20:00:00.000	0.2745
2025-06-01 19:00:00.000	0.2568
2025-06-01 18:00:00.000	0.1859
2025-06-01 17:00:00.000	0.1618
2025-06-01 16:00:00.000	0.1559
2025-06-01 15:00:00.000	0.1444
2025-06-01 14:00:00.000	0.1387
2025-06-01 13:00:00.000	0.1476
2025-06-01 12:00:00.000	0.1565
2025-06-01 11:00:00.000	0.1605
2025-06-01 10:00:00.000	0.1623
2025-06-01 09:00:00.000	0.163
2025-06-01 08:00:00.000	0.1659
2025-06-01 07:00:00.517	0.163
2025-06-01 07:00:00.000	0.1785
2025-06-01 06:00:00.004	0.1659
2025-06-01 06:00:00.000	0.2057
2025-06-01 05:00:00.423	0.1785
2025-06-01 05:00:00.000	0.2417
2025-06-01 04:00:00.332	0.2057
2025-06-01 04:00:00.000	0.2495
2025-06-01 03:00:00.003	0.2417
2025-06-01 03:00:00.000	0.2512
2025-06-01 02:00:00.014	0.2495
2025-06-01 02:00:00.000	0.2548
2025-06-01 01:00:00.197	0.2512
2025-06-01 01:00:00.000	0.2644
2025-06-01 00:00:00.010	0.2548
2025-06-01 00:00:00.000	0.2731
2025-05-31 23:00:00.522	0.2644
2025-05-31 23:00:00.000	0.2845
2025-05-31 22:00:00.546	0.2731
2025-05-31 22:00:00.000	0.3219
2025-05-31 21:00:00.392	0.2845
2025-05-31 21:00:00.000	0.3919
2025-05-31 20:00:00.133	0.3219
2025-05-31 20:00:00.000	0.3919
2025-05-31 19:00:00.000	0.3194
2025-05-31 18:00:00.377	0.3919
2025-05-31 18:00:00.000	0.2687
2025-05-31 17:00:00.008	0.3194
2025-05-31 17:00:00.000	0.2123
2025-05-31 16:00:00.062	0.2687
2025-05-31 16:00:00.000	0.1629
2025-05-31 15:00:00.000	0.1594
2025-05-31 14:00:00.000	0.1538
2025-05-31 13:00:00.000	0.1473
2025-05-31 12:00:00.000	0.1594
2025-05-31 11:00:00.000	0.1618
2025-05-31 10:00:00.000	0.163
2025-05-31 09:00:00.000	0.1642
2025-05-31 08:00:00.000	0.2285
2025-05-31 07:00:00.000	0.2637
2025-05-31 06:00:00.000	0.2758
2025-05-31 05:00:00.000	0.28
2025-05-31 04:00:00.000	0.2819
2025-05-31 03:00:00.000	0.2809
2025-05-31 02:00:00.000	0.2805
2025-05-31 01:00:00.000	0.2819
2025-05-31 00:00:00.000	0.2903

and some live ones (it’s 9:44h right now, so they’re 2hours behind)

live
2025-06-01 07:44:19.476	0
2025-06-01 07:44:14.305	0.6
2025-06-01 07:44:10.114	0
2025-06-01 07:44:00.528	0.1
2025-06-01 07:43:47.744	0
2025-06-01 07:43:42.356	3.5
2025-06-01 07:43:38.932	5.5
2025-06-01 07:43:34.001	0.1
2025-06-01 07:43:29.574	0.3
2025-06-01 07:43:24.803	5.7
2025-06-01 07:43:21.500	0
2025-06-01 07:43:16.357	0.8
2025-06-01 07:43:12.024	9.3
2025-06-01 07:42:58.954	0
2025-06-01 07:42:54.504	0.2
2025-06-01 07:42:50.207	0
2025-06-01 07:42:46.763	612.4
2025-06-01 07:42:30.925	0
2025-06-01 07:42:27.289	3.3
2025-06-01 07:42:17.132	0	

so let’s iterate through some stuff:

  1. time on docker host:
    root@BinderHome:~# date So 1. Jun 09:46:16 CEST 2025
  2. time in docker container:
    root@openhabEMS:/openhab# date Sun Jun 1 09:46:58 CEST 2025
  3. time on mariaDB host (Synology for my tests):
    syn@Synology720:~$ date Sun Jun 1 09:47:56 AM CEST 2025
  4. time on mariaDB database:
    SELECT CURRENT_TIME(); 07:49:33

So, I’m not sure, why I didn’t ran into this beforehand, but now I changed the TZ to Europe/Berlin for the test-mariadb-container and I’ll check again later.
For others, solely connecting in the JDBC-mariadb configuration with jdbc:mariadb://192.168.78.18:3307/openHABTest?serverTimezone=Europe/Berlin won’t do! :wink:

ok, now it’s working as it should:


still not sure, why I didn’t find out earlier.

btw: changing the currency to “localeBasedCurrencyProvider” in the settings did not mess up anything, I do get the “EUR/kWh” instead of “DEF/kWh”, but rest should work.

Known problem in OH - somehow for Marketplace bindings this isn’t working: Nevertheless you can set it via Developer API like described here

I put your DB values into the alternating table

  • left clean timestamp - minutes, seconds, milliseconds - all 0
  • right sometimes some milliseconds on top and 2 hours behind!

This is exactly what I mean with

and this would also explain your zick-zack curve.

1 Like

Is there any feedback on Thing Actions with price calculations?

1 Like

I was in the moshpit for a few days! :wink:
In my productive OH4 I don’t work with thing actions obviously. I’ll try to write some rules with actions in the next days.
but: the binding is stable wrt live Tibber information since two weeks now.

apropos: Is your version in principle capable of shorter intervals? The stock exchange - and Tibber - will move to 15m intervals end of September for end users.

Ok, but you can. I replaced it already on my productive OH4 system and work with actions. The 4.3.6 snapshot can be used for OH4 and OH5.

Yes, there’s already a test added. If Tibber doesn’t make any weird changes it will work seamless.

2 Likes

That’s cool! Thanks! I’ll replace it!

ok, found a bit of time to test Thing actions. My feedback is like this:

priceInfoStart/priceInfoEnd

they’re pretty straight forward to use, but the response is a UNIX timestamp, whereas all other returning values are ZonedDateTimes? Would be cool to have at least an parameter, telling the actions to use either? or just return ZDT on every response to make it consistent?

priceList

returns the priceList, but if I leave the parameters empty [‘{}’], it won’t list the next starting point (presently in hourly-mode at 10:45h it should be starting off with 11:00h, but the response starts at 12:00h having 11:00h somewhere in the middle?: )

{
  "size": 14,
  "priceList": [
    {
      "price": 0.124,
      "duration": 3600,
      "level": -2,
      "startsAt": "2025-06-23T12:00:00Z"
    },
    {
      "price": 0.1241,
      "duration": 3600,
      "level": -2,
      "startsAt": "2025-06-23T13:00:00Z"
    },
    {
      "price": 0.1315,
      "duration": 3600,
      "level": -2,
      "startsAt": "2025-06-23T11:00:00Z"
    },
    {
      "price": 0.1333,
      "duration": 3600,
      "level": -2,
      "startsAt": "2025-06-23T14:00:00Z"
    },
...
}

having it listed with {"ascending": true} the 11:00h was sorted an hour earlier after 13:00h, but still not at the first position. :wink:

bestPricePeriod

works in principle as designed.
Two issues:

  1. How do I format the “earliestStart” or “latestStop” parameters? Using UNIX timestamp didn’t work as did the ZDT format?
  2. calculating the needed energy
    Just to be sure: the action expects the “average” power in Watts and does not calculate with the desired energy in Wh? Asking, because many other calculations use Wh (like evcc, AWATTar binding, …)? So, I know, my dish washer uses like 1,6 kWh within a 3h 15m timeframe and uses peak power like 2.200 Watts. So I’d use the parameter 500Watts and 3h 15m to achieve the calculation? Or to put it the other way round: it doesn’t even matter how many Watts I put in, finding the timeframe is just using the duration, but only the “costs” returning using duration * power?
    Could you please also give an example of the curve-Parameter? Do I need to somehow manipulate the timestamp-parameters for the curve, or is it irrelevant, when the timeframe is started, and the action just uses the curve regardless the start of the the timeframe?

bestPriceSchedule

same as the Period wrt to the “power and duration” flag. So, perhaps I know my heatpump uses 4800Watts in average, I then put in the combination with power/duration regardless as with the bestPricePeriod..?