From f871501135dde31222b463874f9f6440d097651a Mon Sep 17 00:00:00 2001 From: Christian Kemper Date: Tue, 12 Aug 2025 13:07:59 +0200 Subject: [PATCH] [tibber] Add support for power consumption and production in one channel (#19124) * [tibber] Add support for power consumption and production in one channel Signed-off-by: Christian Kemper --- bundles/org.openhab.binding.tibber/README.md | 78 ++++++++++--------- .../internal/TibberBindingConstants.java | 1 + .../internal/handler/TibberHandler.java | 27 ++++++- .../resources/OH-INF/i18n/tibber.properties | 2 + .../resources/OH-INF/thing/live-group.xml | 4 + .../resources/OH-INF/thing/thing-types.xml | 2 +- .../resources/OH-INF/update/instructions.xml | 8 ++ 7 files changed, 79 insertions(+), 43 deletions(-) diff --git a/bundles/org.openhab.binding.tibber/README.md b/bundles/org.openhab.binding.tibber/README.md index 5aa23bca78..c655dcc5d6 100644 --- a/bundles/org.openhab.binding.tibber/README.md +++ b/bundles/org.openhab.binding.tibber/README.md @@ -78,21 +78,22 @@ The items connected to the above channels needs to be stored in e.g. [InfluxDB]( Live information from Tibber Pulse. All values 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 | -| 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 | +| 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 @@ -441,29 +442,30 @@ Thing tibber:tibberapi:xyz [ homeid="xxx", token="xxxxxxx", updateHour=13 ] ### `demo.items` Example ```java -Number:EnergyPrice Tibber_API_Spot_Prices "Spot Prices" {channel="tibber:tibberapi:xyz:price#spot-price"} -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:EnergyPrice Tibber_API_Spot_Prices "Spot Prices" {channel="tibber:tibberapi:xyz:price#spot-price"} +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: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: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#consumption-and-production"} +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"} +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"} ``` diff --git a/bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/TibberBindingConstants.java b/bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/TibberBindingConstants.java index 8c0e0fced7..838f840bc9 100644 --- a/bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/TibberBindingConstants.java +++ b/bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/TibberBindingConstants.java @@ -55,6 +55,7 @@ public class TibberBindingConstants { public static final String CHANNEL_PRODUCTION = "production"; public static final String CHANNEL_MIN_PRODUCTION = "minimum-production"; public static final String CHANNEL_PEAK_PRODUCTION = "peak-production"; + public static final String CHANNEL_POWER_BALANCE = "power-balance"; public static final String CHANNEL_VOLTAGE_1 = "voltage1"; public static final String CHANNEL_VOLTAGE_2 = "voltage2"; public static final String CHANNEL_VOLTAGE_3 = "voltage3"; diff --git a/bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/handler/TibberHandler.java b/bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/handler/TibberHandler.java index e5546dbcac..70ebdf8d47 100644 --- a/bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/handler/TibberHandler.java +++ b/bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/handler/TibberHandler.java @@ -483,16 +483,12 @@ public class TibberHandler extends BaseThingHandler { updateChannel(CHANNEL_GROUP_STATISTICS, CHANNEL_DAILY_PRODUCTION, value, "kWh"); value = Utils.getJsonValue(jsonData, "accumulatedProductionLastHour"); updateChannel(CHANNEL_GROUP_STATISTICS, CHANNEL_LAST_HOUR_PRODUCTION, value, "kWh"); - value = Utils.getJsonValue(jsonData, "power"); - updateChannel(CHANNEL_GROUP_LIVE, CHANNEL_CONSUMPTION, value, "W"); value = Utils.getJsonValue(jsonData, "minPower"); updateChannel(CHANNEL_GROUP_LIVE, CHANNEL_MIN_COSNUMPTION, value, "W"); value = Utils.getJsonValue(jsonData, "maxPower"); updateChannel(CHANNEL_GROUP_LIVE, CHANNEL_PEAK_CONSUMPTION, value, "W"); value = Utils.getJsonValue(jsonData, "averagePower"); updateChannel(CHANNEL_GROUP_LIVE, CHANNEL_AVERAGE_CONSUMPTION, value, "W"); - value = Utils.getJsonValue(jsonData, "powerProduction"); - updateChannel(CHANNEL_GROUP_LIVE, CHANNEL_PRODUCTION, value, "W"); value = Utils.getJsonValue(jsonData, "minPowerProduction"); updateChannel(CHANNEL_GROUP_LIVE, CHANNEL_MIN_PRODUCTION, value, "W"); value = Utils.getJsonValue(jsonData, "maxPowerProduction"); @@ -509,6 +505,29 @@ public class TibberHandler extends BaseThingHandler { updateChannel(CHANNEL_GROUP_LIVE, CHANNEL_CURRENT_2, value, "A"); value = Utils.getJsonValue(jsonData, "currentL3"); updateChannel(CHANNEL_GROUP_LIVE, CHANNEL_CURRENT_3, value, "A"); + + String consumption = Utils.getJsonValue(jsonData, "power"); + String production = Utils.getJsonValue(jsonData, "powerProduction"); + updateChannel(CHANNEL_GROUP_LIVE, CHANNEL_CONSUMPTION, consumption, "W"); + updateChannel(CHANNEL_GROUP_LIVE, CHANNEL_PRODUCTION, production, "W"); + double consumptionValue = parseValueSafely(consumption, "consumption"); + double productionValue = parseValueSafely(production, "production"); + + updateChannel(CHANNEL_GROUP_LIVE, CHANNEL_POWER_BALANCE, String.valueOf(consumptionValue - productionValue), + "W"); + } + } + + private double parseValueSafely(@Nullable String value, String valueType) { + if (value == null || value.isBlank() || EMPTY_VALUE.equals(value) || NULL_VALUE.equals(value)) { + return 0.0; + } + + try { + return Double.parseDouble(value); + } catch (NumberFormatException e) { + logger.error("Unable to parse {} value: {}. Assuming 0.", valueType, value, e); + return 0.0; } } diff --git a/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/i18n/tibber.properties b/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/i18n/tibber.properties index 70d20a3e97..2a3b3498ce 100644 --- a/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/i18n/tibber.properties +++ b/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/i18n/tibber.properties @@ -41,6 +41,8 @@ channel-group-type.tibber.live.channel.peak-production.label = Peak Production channel-group-type.tibber.live.channel.peak-production.description = Maximum net power production since midnight in watts channel-group-type.tibber.live.channel.production.label = Live Production channel-group-type.tibber.live.channel.production.description = Net power production at the moment in watts +channel-group-type.tibber.live.channel.power-balance.label = Power Balance +channel-group-type.tibber.live.channel.power-balance.description = Current power consumption (as positive value) and production (as negative value) channel-group-type.tibber.live.channel.voltage1.label = Voltage 1 channel-group-type.tibber.live.channel.voltage1.description = Electric potential on phase 1 channel-group-type.tibber.live.channel.voltage2.label = Voltage 2 diff --git a/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/thing/live-group.xml b/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/thing/live-group.xml index 35a83ddefa..c3fee9f536 100644 --- a/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/thing/live-group.xml +++ b/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/thing/live-group.xml @@ -35,6 +35,10 @@ Maximum net power production since midnight in watts + + + Current power consumption (as positive value) and production (as negative value) + Electric potential on phase 1 diff --git a/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/thing/thing-types.xml index 5af549ac60..71ce71ed8f 100644 --- a/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/thing/thing-types.xml @@ -16,7 +16,7 @@ Tibber - 4 + 5 diff --git a/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/update/instructions.xml index ee4431e765..aea50ae1d3 100644 --- a/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/update/instructions.xml +++ b/bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/update/instructions.xml @@ -177,6 +177,14 @@ Average power consumption since midnight in watts + + + + tibber:power + + Current power consumption (as positive value) and production (as negative value) + +