Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[energidataservice] Add support for persisting historical and upcoming prices #15864

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions bundles/org.openhab.binding.energidataservice/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ To include VAT for items linked to the `Number` channels, the [VAT profile](http
This must be installed separately.
Once installed, simply select "Value-Added Tax" as Profile when linking an item.

#### Persisting Time Series

The binding offers support for persisting both historical and upcoming prices.
The recommended persistence strategy is `forecast`, as it ensures a clean history without redundancy.
Prices from the past 24 hours and all forthcoming prices will be stored.
Any changes that impact published prices (e.g. selecting or deselecting VAT Profile) will result in the replacement of persisted prices within this period.

#### Net Tariff

Discounts are automatically taken into account for channel `net-tariff` so that it represents the actual price.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package org.openhab.binding.energidataservice.internal.handler;

import static org.openhab.binding.energidataservice.internal.EnergiDataServiceBindingConstants.*;
import static org.openhab.core.types.TimeSeries.Policy.REPLACE;

import java.math.BigDecimal;
import java.time.Duration;
Expand All @@ -24,6 +25,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Currency;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
Expand Down Expand Up @@ -65,6 +67,7 @@
import org.openhab.core.thing.binding.ThingHandlerService;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.TimeSeries;
import org.openhab.core.types.UnDefType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -180,6 +183,7 @@ private void refreshElectricityPrices() {

updateStatus(ThingStatus.ONLINE);
updatePrices();
updateTimeSeries();

if (isLinked(CHANNEL_SPOT_PRICE) || isLinked(CHANNEL_HOURLY_PRICES)) {
if (cacheManager.getNumberOfFutureSpotPrices() < 13) {
Expand Down Expand Up @@ -348,6 +352,50 @@ private void updateHourlyPrices() {
updateState(CHANNEL_HOURLY_PRICES, new StringType(gson.toJson(targetPrices)));
}

private void updateTimeSeries() {
TimeSeries spotPriceTimeSeries = new TimeSeries(REPLACE);
Map<DatahubTariff, TimeSeries> datahubTimeSeriesMap = new HashMap<>();
for (DatahubTariff datahubTariff : DatahubTariff.values()) {
datahubTimeSeriesMap.put(datahubTariff, new TimeSeries(REPLACE));
}

Map<Instant, BigDecimal> spotPriceMap = cacheManager.getSpotPrices();
List<Entry<Instant, BigDecimal>> spotPrices = spotPriceMap.entrySet().stream()
.sorted(Map.Entry.comparingByKey()).toList();
for (Entry<Instant, BigDecimal> spotPrice : spotPrices) {
Instant hourStart = spotPrice.getKey();
if (isLinked(CHANNEL_SPOT_PRICE)) {
spotPriceTimeSeries.add(hourStart, new DecimalType(spotPrice.getValue()));
}
for (Map.Entry<DatahubTariff, TimeSeries> entry : datahubTimeSeriesMap.entrySet()) {
DatahubTariff datahubTariff = entry.getKey();
String channelId = datahubTariff.getChannelId();
if (!isLinked(channelId)) {
continue;
}
BigDecimal tariff = cacheManager.getTariff(datahubTariff, hourStart);
if (tariff != null) {
TimeSeries timeSeries = entry.getValue();
timeSeries.add(hourStart, new DecimalType(tariff));
}
}
}
if (spotPriceTimeSeries.size() > 0) {
sendTimeSeries(CHANNEL_SPOT_PRICE, spotPriceTimeSeries);
}
for (Map.Entry<DatahubTariff, TimeSeries> entry : datahubTimeSeriesMap.entrySet()) {
DatahubTariff datahubTariff = entry.getKey();
String channelId = datahubTariff.getChannelId();
if (!isLinked(channelId)) {
continue;
}
TimeSeries timeSeries = entry.getValue();
if (timeSeries.size() > 0) {
sendTimeSeries(channelId, timeSeries);
}
}
}

/**
* Get the configured {@link Currency} for spot prices.
*
Expand Down