Skip to content

Commit

Permalink
[tibber] Add channel for tomorrows prices and timestamps as JSON array (
Browse files Browse the repository at this point in the history
openhab#13416)

Signed-off-by: Arne Seime <arne.seime@gmail.com>
  • Loading branch information
seime authored and borazslo committed Jan 7, 2023
1 parent 5b0db72 commit 0eb97c0
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 21 deletions.
132 changes: 119 additions & 13 deletions bundles/org.openhab.binding.tibber/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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):

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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"}
```
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
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;
Expand Down Expand Up @@ -149,20 +150,24 @@ public void getURLInput(String url) throws IOException {
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());
Expand All @@ -171,7 +176,7 @@ public void getURLInput(String url) throws IOException {
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);
Expand All @@ -191,7 +196,7 @@ public void getURLInput(String url) throws IOException {
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public InputStream connectionInputStream(String homeId) {

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));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Original file line number Diff line number Diff line change
Expand Up @@ -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"/>
Expand Down Expand Up @@ -115,4 +116,10 @@
<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>

0 comments on commit 0eb97c0

Please sign in to comment.