]> git.basschouten.com Git - openhab-addons.git/commitdiff
[tibber] Add channel for tomorrows prices and timestamps as JSON array (#13416)
authorArne Seime <seime@users.noreply.github.com>
Tue, 11 Oct 2022 20:14:19 +0000 (22:14 +0200)
committerGitHub <noreply@github.com>
Tue, 11 Oct 2022 20:14:19 +0000 (22:14 +0200)
Signed-off-by: Arne Seime <arne.seime@gmail.com>
bundles/org.openhab.binding.tibber/README.md
bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/TibberBindingConstants.java
bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/handler/TibberHandler.java
bundles/org.openhab.binding.tibber/src/main/java/org/openhab/binding/tibber/internal/handler/TibberPriceConsumptionHandler.java
bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/i18n/tibber.properties
bundles/org.openhab.binding.tibber/src/main/resources/OH-INF/thing/thing-types.xml

index 7cdd9d29a5b694e77df1168fbc3a715fcd2b2464..3407a3ef98e152fec89d4167f476ca17191e6849 100644 (file)
@@ -19,19 +19,20 @@ 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      |
+| 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      |
 
 Tibber Pulse (optional):
 
@@ -97,6 +98,110 @@ Retrieve personal token and HomeId from description above, and initialize/start
 
 Tibber API will be auto discovered if provided input is correct.
 
+## Tomorrow prices
+
+Example of tomorrow prices data structure - an array of tuples:
+
+```json
+[
+  {
+    "startsAt": "2022-09-27T00:00:00.000+02:00",
+    "total": 3.8472
+  },
+  {
+    "startsAt": "2022-09-27T01:00:00.000+02:00",
+    "total": 3.0748
+  },
+  {
+    "startsAt": "2022-09-27T02:00:00.000+02:00",
+    "total": 2.2725
+  },
+  {
+    "startsAt": "2022-09-27T03:00:00.000+02:00",
+    "total": 2.026
+  },
+  {
+    "startsAt": "2022-09-27T04:00:00.000+02:00",
+    "total": 2.6891
+  },
+  {
+    "startsAt": "2022-09-27T05:00:00.000+02:00",
+    "total": 3.7821
+  },
+  {
+    "startsAt": "2022-09-27T06:00:00.000+02:00",
+    "total": 3.9424
+  },
+  {
+    "startsAt": "2022-09-27T07:00:00.000+02:00",
+    "total": 4.158
+  },
+  {
+    "startsAt": "2022-09-27T08:00:00.000+02:00",
+    "total": 4.2648
+  },
+  {
+    "startsAt": "2022-09-27T09:00:00.000+02:00",
+    "total": 4.2443
+  },
+  {
+    "startsAt": "2022-09-27T10:00:00.000+02:00",
+    "total": 4.2428
+  },
+  {
+    "startsAt": "2022-09-27T11:00:00.000+02:00",
+    "total": 4.2061
+  },
+  {
+    "startsAt": "2022-09-27T12:00:00.000+02:00",
+    "total": 4.1458
+  },
+  {
+    "startsAt": "2022-09-27T13:00:00.000+02:00",
+    "total": 3.9396
+  },
+  {
+    "startsAt": "2022-09-27T14:00:00.000+02:00",
+    "total": 3.8563
+  },
+  {
+    "startsAt": "2022-09-27T15:00:00.000+02:00",
+    "total": 4.0364
+  },
+  {
+    "startsAt": "2022-09-27T16:00:00.000+02:00",
+    "total": 4.093
+  },
+  {
+    "startsAt": "2022-09-27T17:00:00.000+02:00",
+    "total": 4.1823
+  },
+  {
+    "startsAt": "2022-09-27T18:00:00.000+02:00",
+    "total": 4.2779
+  },
+  {
+    "startsAt": "2022-09-27T19:00:00.000+02:00",
+    "total": 4.3154
+  },
+  {
+    "startsAt": "2022-09-27T20:00:00.000+02:00",
+    "total": 4.3469
+  },
+  {
+    "startsAt": "2022-09-27T21:00:00.000+02:00",
+    "total": 4.2329
+  },
+  {
+    "startsAt": "2022-09-27T22:00:00.000+02:00",
+    "total": 4.1014
+  },
+  {
+    "startsAt": "2022-09-27T23:00:00.000+02:00",
+    "total": 4.0265
+  }
+]
+```
 
 ## Full Example
 
@@ -139,4 +244,5 @@ Number:Power               TibberAPILivePowerProduction          "Live Power Pro
 Number:Power               TibberAPILiveMinPowerproduction       "Min Power Production [%.0f W]"                  {channel="tibber:tibberapi:7cfae492:live_minPowerproduction"}
 Number:Power               TibberAPILiveMaxPowerproduction       "Max Power Production [%.0f W]"                  {channel="tibber:tibberapi:7cfae492:live_maxPowerproduction"}
 Number:Energy              TibberAPILiveAccumulatedProduction    "Accumulated Production [%.2f kWh]"         {channel="tibber:tibberapi:7cfae492:live_accumulatedProduction"}
+String                     TibberAPITomorrowPrices               "Price per hour tomorrow JSON array"        {channel="tibber:tibberapi:7cfae492:tomorrow_prices"}
 ```
index d901667a53604977da994c2abc66e1798913ead2..d0d479097f9799b94d14ff1e61db60b8196fbea1 100644 (file)
@@ -44,6 +44,8 @@ public class TibberBindingConstants {
     public static final String CURRENT_TOTAL = "current_total";
     public static final String CURRENT_STARTSAT = "current_startsAt";
     public static final String CURRENT_LEVEL = "current_level";
+
+    public static final String TOMORROW_PRICES = "tomorrow_prices";
     public static final String DAILY_FROM = "daily_from";
     public static final String DAILY_TO = "daily_to";
     public static final String DAILY_COST = "daily_cost";
index ac3461fa714445874557370ca4bbe7442c2399fb..9bfda0ca74e4c138669d307d633bc68f36e6baba 100644 (file)
@@ -53,6 +53,7 @@ import org.openhab.core.types.RefreshType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
 import com.google.gson.JsonSyntaxException;
@@ -149,20 +150,24 @@ public class TibberHandler extends BaseThingHandler {
                 updateStatus(ThingStatus.ONLINE);
             }
 
-            JsonObject object = (JsonObject) JsonParser.parseString(jsonResponse);
+            JsonObject rootJsonObject = (JsonObject) JsonParser.parseString(jsonResponse);
 
             if (jsonResponse.contains("total")) {
                 try {
-                    JsonObject myObject = object.getAsJsonObject("data").getAsJsonObject("viewer")
+                    JsonObject current = rootJsonObject.getAsJsonObject("data").getAsJsonObject("viewer")
                             .getAsJsonObject("home").getAsJsonObject("currentSubscription").getAsJsonObject("priceInfo")
                             .getAsJsonObject("current");
 
-                    updateState(CURRENT_TOTAL, new DecimalType(myObject.get("total").toString()));
-                    String timestamp = myObject.get("startsAt").toString().substring(1, 20);
+                    updateState(CURRENT_TOTAL, new DecimalType(current.get("total").toString()));
+                    String timestamp = current.get("startsAt").toString().substring(1, 20);
                     updateState(CURRENT_STARTSAT, new DateTimeType(timestamp));
                     updateState(CURRENT_LEVEL,
-                            new StringType(myObject.get("level").toString().replaceAll("^\"|\"$", "")));
+                            new StringType(current.get("level").toString().replaceAll("^\"|\"$", "")));
 
+                    JsonArray tomorrow = rootJsonObject.getAsJsonObject("data").getAsJsonObject("viewer")
+                            .getAsJsonObject("home").getAsJsonObject("currentSubscription").getAsJsonObject("priceInfo")
+                            .getAsJsonArray("tomorrow");
+                    updateState(TOMORROW_PRICES, new StringType(tomorrow.toString()));
                 } catch (JsonSyntaxException e) {
                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                             "Error communicating with Tibber API: " + e.getMessage());
@@ -171,7 +176,7 @@ public class TibberHandler extends BaseThingHandler {
             if (jsonResponse.contains("daily") && !jsonResponse.contains("\"daily\":{\"nodes\":[]")
                     && !jsonResponse.contains("\"daily\":null")) {
                 try {
-                    JsonObject myObject = (JsonObject) object.getAsJsonObject("data").getAsJsonObject("viewer")
+                    JsonObject myObject = (JsonObject) rootJsonObject.getAsJsonObject("data").getAsJsonObject("viewer")
                             .getAsJsonObject("home").getAsJsonObject("daily").getAsJsonArray("nodes").get(0);
 
                     String timestampDailyFrom = myObject.get("from").toString().substring(1, 20);
@@ -191,7 +196,7 @@ public class TibberHandler extends BaseThingHandler {
             if (jsonResponse.contains("hourly") && !jsonResponse.contains("\"hourly\":{\"nodes\":[]")
                     && !jsonResponse.contains("\"hourly\":null")) {
                 try {
-                    JsonObject myObject = (JsonObject) object.getAsJsonObject("data").getAsJsonObject("viewer")
+                    JsonObject myObject = (JsonObject) rootJsonObject.getAsJsonObject("data").getAsJsonObject("viewer")
                             .getAsJsonObject("home").getAsJsonObject("hourly").getAsJsonArray("nodes").get(0);
 
                     String timestampHourlyFrom = myObject.get("from").toString().substring(1, 20);
index dcd92f4c2aca36e330ced4a8619174a85b76205e..a78f1c4e7ec3e20d1390bbcc16a294a67cc68c9b 100644 (file)
@@ -33,7 +33,7 @@ public class TibberPriceConsumptionHandler {
 
     public InputStream getInputStream(String homeId) {
         String Query = "{\"query\": \"{viewer {home (id: \\\"" + homeId
-                + "\\\") {currentSubscription {priceInfo {current {total startsAt level }}} daily: consumption(resolution: DAILY, last: 1) {nodes {from to cost unitPrice consumption consumptionUnit}} hourly: consumption(resolution: HOURLY, last: 1) {nodes {from to cost unitPrice consumption consumptionUnit}}}}}\"}";
+                + "\\\") {currentSubscription {priceInfo {current {total startsAt level } tomorrow { startsAt total }}} daily: consumption(resolution: DAILY, last: 1) {nodes {from to cost unitPrice consumption consumptionUnit}} hourly: consumption(resolution: HOURLY, last: 1) {nodes {from to cost unitPrice consumption consumptionUnit}}}}}\"}";
         return new ByteArrayInputStream(Query.getBytes(StandardCharsets.UTF_8));
     }
 
index 3699fbd5332ccd690ac993ce52464687ddf27f7e..eed2a67049563039dff264405ec74b01eede1405 100644 (file)
@@ -39,3 +39,5 @@ channel-type.tibber.timestamp.label = Timestamp
 channel-type.tibber.timestamp.description = Timestamp for measurement/change
 channel-type.tibber.voltage.label = Voltage
 channel-type.tibber.voltage.description = Voltage on given Phase
+channel-type.tibber.tomorrow_prices.label = Prices for tomorrow as a JSON array
+channel-type.tibber.tomorrow_prices.description = JSON array of tuples startsAt,total, e.g. {["startsAt": "2022-09-10T00:00:00+02:00", "total": 5.332}, {"startsAt": ...}]}. See binding documantation for full example.
index ef320c4d10d9fa4ec32337192e27c957301b29bc..d990328aec375bc712385bf9989bc3ecddbbeb95 100644 (file)
@@ -11,6 +11,7 @@
                        <channel id="current_total" typeId="price"/>
                        <channel id="current_startsAt" typeId="timestamp"/>
                        <channel id="current_level" typeId="level"/>
+                       <channel id="tomorrow_prices" typeId="tomorrow_prices"/>
                        <channel id="daily_from" typeId="timestamp"/>
                        <channel id="daily_to" typeId="timestamp"/>
                        <channel id="daily_cost" typeId="cost"/>
                <description>Accumulated Production since Midnight</description>
                <state pattern="%.3f %unit%"></state>
        </channel-type>
+       <channel-type id="tomorrow_prices" advanced="true">
+               <item-type>String</item-type>
+               <label>Prices for tomorrow as a JSON array</label>
+               <description>JSON array of tuples startsAt,total, e.g. {["startsAt": "2022-09-10T00:00:00+02:00", "total": 5.332},
+                       {"startsAt": ...}]. See binding documantation for full example.</description>
+       </channel-type>
 </thing:thing-descriptions>