# Tibber Binding

The Tibber Binding retrieves prices from the Tibber API (opens new window). If you have Tibber Pulse hardware, you can also use the live group and statistics group.

# Supported Things

Type ID Description
Thing tibberapi Connection to Tibber API

# Thing Configuration

Name Type Description Default Required
token text Tibber Personal Token N/A yes
homeid text Tibber Home ID N/A yes
updateHour integer Local hour when spot prices are updated 13 yes

Note: The Tibber token is retrieved from your Tibber account: Tibber Account (opens new window)

Note: The Tibber Home ID is retrieved from developer.tibber.com (opens new window):

  • Sign in (Tibber user account) and "load" personal token.
  • Copy query from below and paste into the Tibber API Explorer, and run query.
  • If Tibber Pulse is connected, the Tibber API Explorer will report "true" for "realTimeConsumptionEnabled"
  • Copy the Home ID from the Tibber API Explorer, without quotation marks, and use it in the binding configuration.
{
  viewer {
    homes {
      id
      features {
        realTimeConsumptionEnabled
      }
    }
  }
}

If you have multiple Home IDs/Pulse devices, create separate Things for each Home ID.

# Channels

# price group

Current and forecast Tibber price information. All values are read-only.

Channel ID Type Description Time Series
total Number:EnergyPrice Total price including energy and taxes yes
spot Number:EnergyPrice Spot prices for energy today and tomorrow yes
tax Number:EnergyPrice Taxes and additional expenses yes
level Number Price levels for today and tomorrow yes
average Number:EnergyPrice Average price from last 24 hours yes

Channel spot-price is deprecated and will be removed in the next major update. It's still available as an advanced channel. The naming was misleading as it reflected the total price and not the Nord Pool spot price (opens new window) used by Tibber.

The level number maps the Tibber Rating (opens new window) into numbers. Zero reflects normal price, while values above 0 are expensive and values below 0 are cheap.

Mapping:

  • Very Cheap: -2
  • Cheap: -1
  • Normal: 0
  • Expensive: 1
  • Very Expensive: 2

The average values are not delivered by the Tibber API. They are calculated by the binding to provide a trend line for the last 24 hours. After the initial setup, the average values will remain NULL until the next day because the previous 24 h prices cannot be obtained by the Tibber API.

Please note that time series are not supported by the default rrd4j (opens new window) persistence. The items connected to the above channels need to be stored in, e.g., InfluxDB (opens new window) or InMemory (opens new window).

# Trigger Channels

Channel event can trigger the following events:

Event Description
DAY_AHEAD_AVAILABLE Day-ahead prices are available

# live group

Live information from Tibber Pulse. All values are read-only.

Channel ID Type Description
consumption Number:Power Consumption at the moment in watts
minimum-consumption Number:Power Minimum power consumption since midnight in watts
peak-consumption Number:Power Peak power consumption since midnight in watts
average-consumption Number:Power Average power consumption since midnight in watts
production Number:Power Net power production at the moment in watts
minimum-production Number:Power Minimum net power production since midnight in watts
peak-production Number:Power Maximum net power production since midnight in watts
power-balance Number:Power Current power consumption (as positive value) and production (as negative value)
voltage1 Number:ElectricPotential Electric potential on phase 1
voltage2 Number:ElectricPotential Electric potential on phase 2
voltage3 Number:ElectricPotential Electric potential on phase 3
current1 Number:ElectricCurrent Electric current on phase 1
current2 Number:ElectricCurrent Electric current on phase 2
current3 Number:ElectricCurrent Electric current on phase 3

# statistics group

Statistical information about total, daily, and last-hour energy consumption and production. All values are read-only.

Channel ID Type Description
total-consumption Number:Energy Total energy consumption measured by Tibber Pulse meter
daily-consumption Number:Energy Energy consumed since midnight in kilowatt-hours
daily-cost Number:Currency Accumulated cost since midnight
last-hour-consumption Number:Energy Energy consumed since last hour shift in kilowatt-hours
total-production Number:Energy Total energy production measured by Tibber Pulse meter
daily-production Number:Energy Net energy produced since midnight in kilowatt-hours
last-hour-production Number:Energy Net energy produced since last hour shift in kilowatt-hours

# Thing Actions

Thing actions can be used to perform calculations on the currently available price information cached by the binding. The cache contains energy prices for today and, after reaching the updateHour, also for tomorrow. This helps plan when to run a device and at what cost.

Performing a calculation requires a parameters object containing, e.g., your boundaries for the calculation. The parameter object allows two types: a Java Map or a JSON String. The result is returned as a JSON-encoded String. See the sections below for the result format. If the action cannot be performed, a warning will be logged and an empty String will be returned. Some real-life scenarios are shown in the Thing Actions section.

# priceInfoStart

Returns the starting point as an Instant of the first available energy price. Calculations must not start before this timestamp.

In case of error Instant.MAX is returned.

# priceInfoEnd

Returns the end point as an Instant of the last available energy price. Calculations must not extend beyond this timestamp.

In case of error Instant.MIN is returned.

# listPrices

List prices in ascending or descending price order. Use persistence extensions (opens new window) if you need time ordering.

# Parameters

Name Type Description Default Required
earliestStart Instant Earliest start time now no
latestEnd Instant Latest end time priceInfoEnd no
ascending boolean Price sorting order true no

# Example

rule "Tibber Price List"
when
    System started // use your trigger
then
    var actions = getActions("tibber","tibber:tibberapi:xyz")
    // parameters empty => default parameters are used = starting from now till end of available price information, ascending
    var parameters = "{}"
    var result = actions.listPrices(parameters)
    val numberOfPrices = transform("JSONPATH", "$.size", result)
    logInfo("TibberPriceList",result)
    for(var i=0; i<Integer.valueOf(numberOfPrices); i++) {
        // get values and convert them into correct format
        val priceString = transform("JSONPATH", "$.priceList["+i+"].price", result)
        val price = Double.valueOf(priceString)
        val startsAtString = transform("JSONPATH", "$.priceList["+i+"].startsAt", result)
        val startsAt = Instant.parse(startsAtString)
        logInfo("TibberPriceList","PriceInfo "+i+" : " + price + " Starts at : " + startsAt.atZone(ZoneId.systemDefault()))
    }
end

# Console output

2025-05-29 15:52:31.345 [INFO ] [ab.core.model.script.TibberPriceList] - PriceInfo 0 : 0.1829 Starts at : 2025-05-30T13:00+02:00[Europe/Berlin]
2025-05-29 15:52:31.349 [INFO ] [ab.core.model.script.TibberPriceList] - PriceInfo 1 : 0.183 Starts at : 2025-05-30T14:00+02:00[Europe/Berlin]
2025-05-29 15:52:31.352 [INFO ] [ab.core.model.script.TibberPriceList] - PriceInfo 2 : 0.1842 Starts at : 2025-05-29T15:52:31.341193101+02:00[Europe/Berlin]
...

# Result

JSON-encoded String result with keys

Key Type Description
size int Size of price list
priceList JSON array Array of priceInfo entries

JSON Object priceInfo

Key Type Description
startsAt String String encoded Instant
duration int Price duration in seconds
price double Price in your currency

# Example

{
    "size": 4,
    "priceList": [
        {
            "price": 0.1623,
            "duration": 3600,
            "level": -1,
            "startsAt": "2025-06-01T12:00:00Z"
        },
        {
            "price": 0.168,
            "duration": 3600,
            "level": -1,
            "startsAt": "2025-06-01T13:00:00Z"
        },
        {
            "price": 0.1712,
            "duration": 3600,
            "level": -1,
            "startsAt": "2025-06-01T11:00:00Z"
        },
        {
            "price": 0.1794,
            "duration": 3600,
            "level": -1,
            "startsAt": "2025-06-01T14:00:00Z"
        }
    ]
}

# bestPricePeriod

Calculates the lowest cost for a consecutive period. For use cases like a dishwasher or laundry.

# Parameters

Name Type Description Default Required
earliestStart Instant Earliest start time now no
latestStop Instant Latest end time priceInfoEnd no
power int Power in watts N/A no
duration String Duration as String with units h,m or s N/A true
curve JsonArray Array with curveEntry elements N/A no

Provide either

  • power and duration for constant consumption or
  • curve for sophisticated use cases like a recorded laundry power time series

JSON Object curveEntry

Key Type Description
timestamp String String encoded Instant
power int Power in watts
duration int Duration in seconds

# Example

import java.util.Map;

var Timer bestPriceTimer = null

rule "Tibber Best Price"
when
    System started // use your trigger
then
    // get actions
    var actions = getActions("tibber","tibber:tibberapi:xyz")
    //create parameters for calculation
    var parameters = Map.of("duration", "1 h 34 m")
    // perform calculation
    var result = actions.bestPricePeriod(parameters)
    // log result, no prices given because no power value given
    logInfo("TibberBestPrice",result)
    
    // parameters with power value - as example use java Map instead of JSON  
    parameters = Map.of("duration", "1 h 34 m","power",423,"latestEnd",Instant.now().plusSeconds(7200))
    result = actions.bestPricePeriod(parameters)
    logInfo("TibberBestPrice",result)
    // calculate time between now and cheapest start and start timer to execute action
    val startsAt = transform("JSONPATH", "$.cheapestStart", result)
    var secondsTillStart = Duration.between(Instant.now(), Instant.parse(startsAt)).getSeconds()
    // if the start should happen immediately, avoid negative values
    secondsTillStart = Math::max(0,secondsTillStart) 
    bestPriceTimer = createTimer(now.plusSeconds(secondsTillStart), [|           
        logInfo("TibberBestPrice","Start your device")
    ])
end

Console output:

2025-05-29 16:07:40.858 [TRACE] [.internal.calculator.PriceCalculator] - Calculation time 2 ms for 1819 iterations
2025-05-29 16:07:40.860 [INFO ] [ab.core.model.script.TibberBestPrice] - {"cheapestStart":"2025-05-30T11:00:40.856950656Z","mostExpensiveStart":"2025-05-30T18:25:40.856950656Z"}
2025-05-29 16:07:40.861 [TRACE] [.internal.calculator.PriceCalculator] - Calculation time 0 ms for 26 iterations
2025-05-29 16:07:40.863 [INFO ] [ab.core.model.script.TibberBestPrice] - {"highestPrice":0.138712416,"lowestPrice":0.13126169399999998,"cheapestStart":"2025-05-29T14:07:40.861730141Z","averagePrice":0.134152053,"mostExpensiveStart":"2025-05-29T14:32:40.861730141Z"}
2025-05-29 16:07:40.967 [INFO ] [ab.core.model.script.TibberBestPrice] - Start your device

# Result

JSON-encoded String result with keys

Key Type Description
cheapestStart String Timestamp of cheapest start
lowestPrice double Price of the cheapest period
mostExpensiveStart String Timestamp of most expensive start
highestPrice double Price of the most expensive period
averagePrice double Average price within the period

# Result Example

{
    "highestPrice": 0.18921223574999999,
    "lowestPrice": 0.17497929625,
    "cheapestStart": "2025-05-31T15:12:58.135876781Z",
    "averagePrice": 0.1810258046730769,
    "mostExpensiveStart": "2025-05-31T15:37:58.135876781Z"
}

# bestPriceSchedule

Calculates the lowest cost for a non-consecutive schedule. For use cases like a battery electric vehicle or a heat pump.

# Parameters

Name Type Description Default Required
earliestStart Instant Earliest start time now no
latestStop Instant Latest end time priceInfoEnd no
power int Needed power N/A no
duration int Duration in seconds or String (8h 15m) N/A yes

# Example

rule "Tibber Schedule Calculation"
when
    System started // use your trigger
then
    var actions = getActions("tibber","tibber:tibberapi:xyz")
    // long period with constant power value
    var parameters = "{\"power\": 11000, \"duration\": \"8h 15m\"}"
    var result = actions.bestPriceSchedule(parameters)
    // get cost and convert it into double value
    val costString = transform("JSONPATH", "$.cost", result)
    val cost = Double.valueOf(costString)
    val scheduleSize = transform("JSONPATH", "$.size", result)
    logInfo("TibberSchedule",result)
    logInfo("TibberSchedule","Cost : " + cost+" Number of schedules : " + scheduleSize)
    for(var i=0; i<Integer.valueOf(scheduleSize); i++) {
        val schedule = transform("JSONPATH", "$.schedule["+i+"]", result)
        logInfo("TibberSchedule","Schedule "+i+": " + schedule)
        val scheduleStartString = transform("JSONPATH", "$.schedule["+i+"].start", result)
        val scheduleStart = Instant.parse(scheduleStartString)
        logInfo("TibberSchedule","Schedule "+i+" start: " + scheduleStart.atZone(ZoneId.systemDefault()).toString)
    }
end

Console output

2025-05-29 19:42:38.223 [INFO ] [hab.core.model.script.TibberSchedule] - {"cost":17.004625,"size":2,"schedule":[{"start":"2025-05-30T08:00:00Z","stop":"2025-05-30T16:00:00Z","duration":28800,"cost":16.407600000000002},{"start":"2025-05-29T23:00:00Z","stop":"2025-05-29T23:15:00Z","duration":900,"cost":0.5970249999999999}]}
2025-05-29 19:42:38.225 [INFO ] [hab.core.model.script.TibberSchedule] - Cost : 17.004625 Number of schedules : 2
2025-05-29 19:42:38.227 [INFO ] [hab.core.model.script.TibberSchedule] - Schedule 0: {start=2025-05-30T08:00:00Z, stop=2025-05-30T16:00:00Z, duration=28800, cost=16.407600000000002}
2025-05-29 19:42:38.230 [INFO ] [hab.core.model.script.TibberSchedule] - Schedule 0 start: 2025-05-30T10:00+02:00[Europe/Berlin]
2025-05-29 19:42:38.232 [INFO ] [hab.core.model.script.TibberSchedule] - Schedule 1: {start=2025-05-29T23:00:00Z, stop=2025-05-29T23:15:00Z, duration=900, cost=0.5970249999999999}
2025-05-29 19:42:38.234 [INFO ] [hab.core.model.script.TibberSchedule] - Schedule 1 start: 2025-05-30T01:00+02:00[Europe/Berlin]

# Result

JSON encoded String result with keys

Key Type Description
size int Number of schedules
schedule JSON array Array of scheduleEntry elements

JSON Object scheduleEntry

Key Type Description
start String Start time (Instant as string)
stop String Stop time (Instant as string)
duration int Duration in seconds
cost double Cost in your currency

# Result Example

{
    "cost": 16.092450000000003,
    "size": 2,
    "schedule": [
        {
            "start": "2025-06-01T08:00:00Z",
            "stop": "2025-06-01T16:00:00Z",
            "duration": 28800,
            "cost": 15.579300000000002
        },
        {
            "start": "2025-06-01T07:00:00Z",
            "stop": "2025-06-01T07:15:00Z",
            "duration": 900,
            "cost": 0.51315
        }
    ]
}

# Full Example

Full example with demo.things and demo.items

# demo.things Example

Thing tibber:tibberapi:xyz [ homeid="xxx", token="xxxxxxx", updateHour=13 ]

# demo.items Example

Number:EnergyPrice          Tibber_API_Spot_Prices              "Spot Prices"                {channel="tibber:tibberapi:xyz:price#spot"}
Number                      Tibber_API_Price_Level              "Price Level"                {channel="tibber:tibberapi:xyz:price#level"}
Number:EnergyPrice          Tibber_API_Average                  "Average Price"              {channel="tibber:tibberapi:xyz:price#average"}

Number:Power                Tibber_API_Live_Consumption         "Live Consumption"           {channel="tibber:tibberapi:xyz:live#consumption"}
Number:Power                Tibber_API_Minimum_Consumption      "Minimum Consumption"        {channel="tibber:tibberapi:xyz:live#minimum-consumption"}
Number:Power                Tibber_API_Peak_Consumption         "Peak Consumption"           {channel="tibber:tibberapi:xyz:live#peak-consumption"}
Number:Power                Tibber_API_Average_Consumption      "Average Consumption"        {channel="tibber:tibberapi:xyz:live#average-consumption"}
Number:Power                Tibber_API_Live_Production          "Live Production"            {channel="tibber:tibberapi:xyz:live#production"}
Number:Power                Tibber_API_Minimum_Production       "Minimum Production"         {channel="tibber:tibberapi:xyz:live#minimum-production"}
Number:Power                Tibber_API_Peak_Production          "Peak Production"            {channel="tibber:tibberapi:xyz:live#peak-production"}
Number:Power                Tibber_API_Power_Balance            "Power Balance"              {channel="tibber:tibberapi:xyz:live#power-balance"}
Number:ElectricPotential    Tibber_API_Voltage_1                "Voltage 1"                  {channel="tibber:tibberapi:xyz:live#voltage1"}
Number:ElectricPotential    Tibber_API_Voltage_2                "Voltage 2"                  {channel="tibber:tibberapi:xyz:live#voltage2"}
Number:ElectricPotential    Tibber_API_Voltage_3                "Voltage 3"                  {channel="tibber:tibberapi:xyz:live#voltage3"}
Number:ElectricCurrent      Tibber_API_Current_1                "Current 1"                  {channel="tibber:tibberapi:xyz:live#current1"}
Number:ElectricCurrent      Tibber_API_Current_2                "Current 2"                  {channel="tibber:tibberapi:xyz:live#current2"}
Number:ElectricCurrent      Tibber_API_Current_3                "Current 3"                  {channel="tibber:tibberapi:xyz:live#current3"}

Number:Energy               Tibber_API_Total_Consumption        "Total Consumption"          {channel="tibber:tibberapi:xyz:statistics#total-consumption"}
Number:Energy               Tibber_API_Daily_Consumption        "Daily Consumption"          {channel="tibber:tibberapi:xyz:statistics#daily-consumption"}
Number:Currency             Tibber_API_Daily_Cost               "Daily Cost"                 {channel="tibber:tibberapi:xyz:statistics#daily-cost"}
Number:Energy               Tibber_API_Last_Hour_Consumption    "Last Hour Consumption"      {channel="tibber:tibberapi:xyz:statistics#last-hour-consumption"}
Number:Energy               Tibber_API_Total_Production         "Total Production"           {channel="tibber:tibberapi:xyz:statistics#total-production"}
Number:Energy               Tibber_API_Daily_Production         "Daily Production"           {channel="tibber:tibberapi:xyz:statistics#daily-production"}
Number:Energy               Tibber_API_Last_Hour_Production     "Last Hour Production"       {channel="tibber:tibberapi:xyz:statistics#last-hour-production"}

# Rule listen to day-ahead price update

rule "Tibber day-ahead prices available"
when
    Channel 'tibber:tibberapi:xyz:price#event' triggered
then
    logInfo("Tibber Update","Price event {}", receivedEvent)
end