]> git.basschouten.com Git - openhab-addons.git/commitdiff
[tibber] Add time series support for Tibber prices (#16275)
authorSönke Küper <soenkekueper@gmx.de>
Mon, 15 Jan 2024 17:46:50 +0000 (18:46 +0100)
committerGitHub <noreply@github.com>
Mon, 15 Jan 2024 17:46:50 +0000 (18:46 +0100)
Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
bundles/org.openhab.binding.tibber/README.md
bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/handler/TibberHandler.java

index 18384df71c1640fd679ac01ac3eba366b65e192f..44fba1ed783d9257eea49fca8278ebd9db826255 100644 (file)
@@ -19,43 +19,47 @@ The channels (i.e. measurements) associated with the Binding:
 
 Tibber Default:
 
-| Channel ID         | Description                                             | Read-only |
-|--------------------|---------------------------------------------------------|-----------|
-| Current Total      | Current Total Price (energy + tax)                      | True      |
-| Starts At          | Current Price Timestamp                                 | True      |
-| Current Level      | Current Price Level                                     | True      |
-| Daily Cost         | Daily Cost (last/previous day)                          | True      |
-| Daily Consumption  | Daily Consumption (last/previous day)                   | True      |
-| Daily From         | Timestamp (daily from)                                  | True      |
-| Daily To           | Timestamp (daily to)                                    | True      |
-| Hourly Cost        | Hourly Cost (last/previous hour)                        | True      |
-| Hourly Consumption | Hourly Consumption (last/previous hour)                 | True      |
-| Hourly From        | Timestamp (hourly from)                                 | True      |
-| Hourly To          | Timestamp (hourly to)                                   | True      |
-| Tomorrow prices    | JSON array of tomorrow's prices. See below for example. | True      |
-| Today prices       | JSON array of today's prices. See below for example.    | True      |
+| Channel ID           | Description                                             | Read-only | Forecast |
+|----------------------|---------------------------------------------------------|-----------|----------|
+| current_total        | Current Total Price (energy + tax)                      | True      | yes      |
+| current_startsAt     | Current Price Timestamp                                 | True      | no       |
+| current_level        | Current Price Level                                     | True      | no       |
+| daily_cost           | Daily Cost (last/previous day)                          | True      | no       |
+| daily_consumption    | Daily Consumption (last/previous day)                   | True      | no       |
+| daily_from           | Timestamp (daily from)                                  | True      | no       |
+| daily_to             | Timestamp (daily to)                                    | True      | no       |
+| hourly_cost          | Hourly Cost (last/previous hour)                        | True      | no       |
+| hourly_consumption   | Hourly Consumption (last/previous hour)                 | True      | no       |
+| hourly_from          | Timestamp (hourly from)                                 | True      | no       |
+| hourly_to            | Timestamp (hourly to)                                   | True      | no       |
+| tomorrow_prices      | JSON array of tomorrow's prices. See below for example. | True      | no       |
+| today_prices         | JSON array of today's prices. See below for example.    | True      | no       |
 
 Tibber Pulse (optional):
 
-| Channel ID              | Description                              | Read-only |
-|-------------------------|------------------------------------------|-----------|
-| Timestamp               | Timestamp for live measurements          | True      |
-| Power                   | Live Power Consumption                   | True      |
-| Last Meter Consumption  | Last Recorded Meter Consumption          | True      |
-| Accumulated Consumption | Accumulated Consumption since Midnight   | True      |
-| Accumulated Cost        | Accumulated Cost since Midnight          | True      |
-| Accumulated Reward      | Accumulated Reward since Midnight        | True      |
-| Currency                | Currency of Cost                         | True      |
-| Min Power               | Min Power Consumption since Midnight     | True      |
-| Average Power           | Average Power Consumption since Midnight | True      |
-| Max Power               | Max Power Consumption since Midnight     | True      |
-| Voltage 1-3             | Voltage per Phase                        | True      |
-| Current 1-3             | Current per Phase                        | True      |
-| Power Production        | Live Power Production                    | True      |
-| Accumulated Production  | Accumulated Production since Midnight    | True      |
-| Last Meter Production   | Last Recorded Meter Production           | True      |
-| Min Power Production    | Min Power Production since Midnight      | True      |
-| Max Power Production    | Max Power Production since Midnight      | True      |
+| Channel ID                  | Description                              | Read-only |
+|-----------------------------|------------------------------------------|-----------|
+| live_timestamp              | Timestamp for live measurements          | True      |
+| live_power                  | Live Power Consumption                   | True      |
+| live_lastMeterConsumption   | Last Recorded Meter Consumption          | True      |
+| live_accumulatedConsumption | Accumulated Consumption since Midnight   | True      |
+| live_accumulatedCost        | Accumulated Cost since Midnight          | True      |
+| live_accumulatedReward      | Accumulated Reward since Midnight        | True      |
+| live_currency               | Currency of Cost                         | True      |
+| live_minPower               | Min Power Consumption since Midnight     | True      |
+| live_averagePower           | Average Power Consumption since Midnight | True      |
+| live_maxPower               | Max Power Consumption since Midnight     | True      |
+| live_voltage1               | Voltage Phase 1                          | True      |
+| live_voltage2               | Voltage Phase  2                         | True      |
+| live_voltage3               | Voltage Phase 3                          | True      |
+| live_current1               | Current Phase 1                          | True      |
+| live_current2               | Current Phase 2                          | True      |
+| live_current3               | Current Phase 3                          | True      |
+| live_powerProduction        | Live Power Production                    | True      |
+| live_accumulatedProduction  | Accumulated Production since Midnight    | True      |
+| live_lastMeterProduction    | Last Recorded Meter Production           | True      |
+| live_minPowerproduction     | Min Power Production since Midnight      | True      |
+| live_maxPowerproduction     | Max Power Production since Midnight      | True      |
 
 ## Binding Configuration
 
@@ -102,6 +106,7 @@ Tibber API will be auto discovered if provided input is correct.
 
 ## Tomorrow and Today Prices
 
+The today and tomorrow prices are served as forecast on the `current_total` channel and as JSON data on the channels `today_prices` and `tomorrow_prices`.
 Example of tomorrow and today prices data structure - an array of tuples:
 
 ```json
index a93a5494a4e02aca70c1643058512e6d41a853b1..d92178866283fcad164e3788881e7666a569970d 100644 (file)
@@ -19,6 +19,9 @@ import java.io.InputStream;
 import java.math.BigDecimal;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.time.Instant;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeParseException;
 import java.util.Properties;
 import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledFuture;
@@ -52,6 +55,7 @@ import org.openhab.core.thing.ThingStatusInfo;
 import org.openhab.core.thing.binding.BaseThingHandler;
 import org.openhab.core.types.Command;
 import org.openhab.core.types.RefreshType;
+import org.openhab.core.types.TimeSeries;
 import org.osgi.framework.FrameworkUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -203,7 +207,10 @@ public class TibberHandler extends BaseThingHandler {
                             .getAsJsonObject("home").getAsJsonObject("currentSubscription").getAsJsonObject("priceInfo")
                             .getAsJsonArray("today");
                     updateState(TODAY_PRICES, new StringType(today.toString()));
-                } catch (JsonSyntaxException e) {
+
+                    TimeSeries timeSeries = buildTimeSeries(today, tomorrow);
+                    sendTimeSeries(CURRENT_TOTAL, timeSeries);
+                } catch (JsonSyntaxException | DateTimeParseException e) {
                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                             "Error communicating with Tibber API: " + e.getMessage());
                 }
@@ -267,6 +274,29 @@ public class TibberHandler extends BaseThingHandler {
         }
     }
 
+    /**
+     * Builds the {@link TimeSeries} that represents the future tibber prices.
+     *
+     * @param today The prices for today
+     * @param tomorrow The prices for tomorrow.
+     * @return The {@link TimeSeries} with future values.
+     */
+    private TimeSeries buildTimeSeries(JsonArray today, JsonArray tomorrow) {
+        final TimeSeries timeSeries = new TimeSeries(TimeSeries.Policy.REPLACE);
+        mapTimeSeriesEntries(today, timeSeries);
+        mapTimeSeriesEntries(tomorrow, timeSeries);
+        return timeSeries;
+    }
+
+    private void mapTimeSeriesEntries(JsonArray prices, TimeSeries timeSeries) {
+        for (JsonElement entry : prices) {
+            JsonObject entryObject = entry.getAsJsonObject();
+            final Instant startsAt = ZonedDateTime.parse(entryObject.get("startsAt").getAsString()).toInstant();
+            final DecimalType value = new DecimalType(entryObject.get("total").getAsString());
+            timeSeries.add(startsAt, value);
+        }
+    }
+
     public void startRefresh(int refresh) {
         if (pollingJob == null) {
             pollingJob = scheduler.scheduleWithFixedDelay(() -> {