Skip to content

Commit

Permalink
Remove obsoleted advanced channel hourly-prices (#16190)
Browse files Browse the repository at this point in the history
Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
  • Loading branch information
jlaur committed Jan 13, 2024
1 parent daea030 commit 9afbe0b
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 92 deletions.
88 changes: 49 additions & 39 deletions bundles/org.openhab.binding.energidataservice/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ It will not impact channels, see [Electricity Tax](#electricity-tax) for further
| transmission-grid-tariff | Number:EnergyPrice | Transmission grid tariff in DKK per kWh | no |
| electricity-tax | Number:EnergyPrice | Electricity tax in DKK per kWh | no |
| reduced-electricity-tax | Number:EnergyPrice | Reduced electricity tax in DKK per kWh. For electric heating customers only | no |
| hourly-prices | String | JSON array with hourly prices from 24 hours ago and onward | yes |

_Please note:_ There is no channel providing the total price.
Instead, create a group item with `SUM` as aggregate function and add the individual price items as children.
Expand Down Expand Up @@ -142,48 +141,16 @@ This reduced rate is made available through channel `reduced-electricity-tax`.
The binding cannot determine or manage rate variations as they depend on metering data.
Usually `reduced-electricity-tax` is preferred when using electricity for heating.

#### Hourly Prices

The format of the `hourly-prices` JSON array is as follows:

```json
[
{
"hourStart": "2023-09-19T18:00:00Z",
"spotPrice": 0.0,
"spotPriceCurrency": "DKK",
"gridTariff": 0.0,
"systemTariff": 0.054,
"transmissionGridTariff": 0.058,
"electricityTax": 0.697,
"reducedElectricityTax": 0.008
},
{
"hourStart": "2023-09-19T19:00:00Z",
"spotPrice": -0.00052,
"spotPriceCurrency": "DKK",
"gridTariff": 0.0,
"systemTariff": 0.054,
"transmissionGridTariff": 0.058,
"electricityTax": 0.697,
"reducedElectricityTax": 0.008
}
]
```

Future spot prices for the next day are usually available around 13:00 CET and are fetched around that time.
Historic prices older than 24 hours are removed from the JSON array each hour.

## Thing Actions

Thing actions can be used to perform calculations as well as import prices directly into rules without deserializing JSON from the [hourly-prices](#hourly-prices) channel.
This is more convenient, much faster, and provides automatic summation of the price components of interest.
Thing actions can be used to perform calculations as well as import prices directly into rules without relying on persistence.
This is convenient, fast, and provides automatic summation of the price components of interest.

Actions use cached data for performing operations.
Since data is only fetched when an item is linked to a channel, there might not be any cached data available.
In this case the data will be fetched on demand and cached afterwards.
The first action triggered on a given day may therefore be a bit slower, and is also prone to failing if the server call fails for any reason.
This potential problem can be prevented by linking the individual channels to items, or by linking the `hourly-prices` channel to an item.
This potential problem can be prevented by linking the individual channels to items.

### `calculateCheapestPeriod`

Expand Down Expand Up @@ -341,8 +308,8 @@ var price = actions.calculatePrice(now.toInstant(), now.plusHours(4).toInstant,
The parameter `priceComponents` is a case-insensitive comma-separated list of price components to include in the returned hourly prices.
These components can be requested:

| Price component | Description |
|------------------------|-------------------------|
| Price component | Description |
|------------------------|--------------------------|
| SpotPrice | Spot price |
| GridTariff | Grid tariff |
| SystemTariff | System tariff |
Expand Down Expand Up @@ -380,9 +347,26 @@ Number GridTariff "Current Grid Tariff" <price> (TotalPrice) { channel="energida
Number SystemTariff "Current System Tariff" <price> (TotalPrice) { channel="energidataservice:service:energidataservice:electricity#system-tariff" [profile="transform:VAT"] }
Number TransmissionGridTariff "Current Transmission Grid Tariff" <price> (TotalPrice) { channel="energidataservice:service:energidataservice:electricity#transmission-grid-tariff" [profile="transform:VAT"] }
Number ElectricityTax "Current Electricity Tax" <price> (TotalPrice) { channel="energidataservice:service:energidataservice:electricity#electricity-tax" [profile="transform:VAT"] }
String HourlyPrices "Hourly Prices" <price> { channel="energidataservice:service:energidataservice:electricity#hourly-prices" }
```

### Persistence Configuration

```java
Strategies {
default = everyChange
}

Items {
SpotPrice,
GridTariff,
SystemTariff,
TransmissionGridTariff,
ElectricityTax: strategy = forecast
}
```

In case persistence is only needed for charts and/or accessing prices from rules, [InMemory Persistence](https://www.openhab.org/addons/persistence/inmemory/) can be used.

### Thing Actions Example

:::: tabs
Expand Down Expand Up @@ -517,3 +501,29 @@ var result = edsActions.calculateCheapestPeriod(time.Instant.now(), time.Instant
:::

::::

### Persistence Rule Example

:::: tabs

::: tab DSL

```javascript
var hourStart = now.plusHours(2).truncatedTo(ChronoUnit.HOURS)
var price = SpotPrice.historicState(hourStart).state
logInfo("Spot price two hours from now", price.toString)
```

:::

::: tab JavaScript

```javascript
var hourStart = time.toZDT().plusHours(2).truncatedTo(time.ChronoUnit.HOURS);
var price = items.SpotPrice.history.historicState(hourStart).quantityState;
console.log("Spot price two hours from now: " + price);
```

:::

::::
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,10 @@ public class EnergiDataServiceBindingConstants {
+ ChannelUID.CHANNEL_GROUP_SEPARATOR + "reduced-electricity-tax";
public static final String CHANNEL_TRANSMISSION_GRID_TARIFF = CHANNEL_GROUP_ELECTRICITY
+ ChannelUID.CHANNEL_GROUP_SEPARATOR + "transmission-grid-tariff";
public static final String CHANNEL_HOURLY_PRICES = CHANNEL_GROUP_ELECTRICITY + ChannelUID.CHANNEL_GROUP_SEPARATOR
+ "hourly-prices";

public static final Set<String> ELECTRICITY_CHANNELS = Set.of(CHANNEL_SPOT_PRICE, CHANNEL_GRID_TARIFF,
CHANNEL_SYSTEM_TARIFF, CHANNEL_TRANSMISSION_GRID_TARIFF, CHANNEL_ELECTRICITY_TAX,
CHANNEL_REDUCED_ELECTRICITY_TAX, CHANNEL_HOURLY_PRICES);
CHANNEL_REDUCED_ELECTRICITY_TAX);

// List of all properties
public static final String PROPERTY_REMAINING_CALLS = "remainingCalls";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.library.unit.CurrencyUnits;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
Expand All @@ -77,8 +76,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;

/**
* The {@link EnergiDataServiceHandler} is responsible for handling commands, which are
* sent to one of the channels.
Expand All @@ -92,19 +89,12 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
private final TimeZoneProvider timeZoneProvider;
private final ApiController apiController;
private final CacheManager cacheManager;
private final Gson gson = new Gson();

private EnergiDataServiceConfiguration config;
private RetryStrategy retryPolicy = RetryPolicyFactory.initial();
private @Nullable ScheduledFuture<?> refreshFuture;
private @Nullable ScheduledFuture<?> priceUpdateFuture;

private record Price(String hourStart, BigDecimal spotPrice, String spotPriceCurrency,
@Nullable BigDecimal gridTariff, @Nullable BigDecimal systemTariff,
@Nullable BigDecimal transmissionGridTariff, @Nullable BigDecimal electricityTax,
@Nullable BigDecimal reducedElectricityTax) {
}

public EnergiDataServiceHandler(Thing thing, HttpClient httpClient, TimeZoneProvider timeZoneProvider) {
super(thing);
this.timeZoneProvider = timeZoneProvider;
Expand Down Expand Up @@ -177,12 +167,12 @@ public Collection<Class<? extends ThingHandlerService>> getServices() {
private void refreshElectricityPrices() {
RetryStrategy retryPolicy;
try {
if (isLinked(CHANNEL_SPOT_PRICE) || isLinked(CHANNEL_HOURLY_PRICES)) {
if (isLinked(CHANNEL_SPOT_PRICE)) {
downloadSpotPrices();
}

for (DatahubTariff datahubTariff : DatahubTariff.values()) {
if (isLinked(datahubTariff.getChannelId()) || isLinked(CHANNEL_HOURLY_PRICES)) {
if (isLinked(datahubTariff.getChannelId())) {
downloadTariffs(datahubTariff);
}
}
Expand All @@ -191,7 +181,7 @@ private void refreshElectricityPrices() {
updatePrices();
updateTimeSeries();

if (isLinked(CHANNEL_SPOT_PRICE) || isLinked(CHANNEL_HOURLY_PRICES)) {
if (isLinked(CHANNEL_SPOT_PRICE)) {
if (cacheManager.getNumberOfFutureSpotPrices() < 13) {
retryPolicy = RetryPolicyFactory.whenExpectedSpotPriceDataMissing(DAILY_REFRESH_TIME_CET,
NORD_POOL_TIMEZONE);
Expand Down Expand Up @@ -315,7 +305,6 @@ private void updatePrices() {
updateCurrentSpotPrice();
Arrays.stream(DatahubTariff.values())
.forEach(tariff -> updateCurrentTariff(tariff.getChannelId(), cacheManager.getTariff(tariff)));
updateHourlyPrices();

reschedulePriceUpdateJob();
}
Expand Down Expand Up @@ -354,30 +343,6 @@ private State getEnergyPrice(BigDecimal price, Currency currency) {
}
}

private void updateHourlyPrices() {
if (!isLinked(CHANNEL_HOURLY_PRICES)) {
return;
}
Map<Instant, BigDecimal> spotPriceMap = cacheManager.getSpotPrices();
Price[] targetPrices = new Price[spotPriceMap.size()];
List<Entry<Instant, BigDecimal>> sourcePrices = spotPriceMap.entrySet().stream()
.sorted(Map.Entry.comparingByKey()).toList();

int i = 0;
for (Entry<Instant, BigDecimal> sourcePrice : sourcePrices) {
Instant hourStart = sourcePrice.getKey();
BigDecimal gridTariff = cacheManager.getTariff(DatahubTariff.GRID_TARIFF, hourStart);
BigDecimal systemTariff = cacheManager.getTariff(DatahubTariff.SYSTEM_TARIFF, hourStart);
BigDecimal transmissionGridTariff = cacheManager.getTariff(DatahubTariff.TRANSMISSION_GRID_TARIFF,
hourStart);
BigDecimal electricityTax = cacheManager.getTariff(DatahubTariff.ELECTRICITY_TAX, hourStart);
BigDecimal reducedElectricityTax = cacheManager.getTariff(DatahubTariff.REDUCED_ELECTRICITY_TAX, hourStart);
targetPrices[i++] = new Price(hourStart.toString(), sourcePrice.getValue(), config.currencyCode, gridTariff,
systemTariff, electricityTax, reducedElectricityTax, transmissionGridTariff);
}
updateState(CHANNEL_HOURLY_PRICES, new StringType(gson.toJson(targetPrices)));
}

private void updateTimeSeries() {
TimeSeries spotPriceTimeSeries = new TimeSeries(REPLACE);
Map<DatahubTariff, TimeSeries> datahubTimeSeriesMap = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ channel-group-type.energidataservice.electricity.channel.transmission-grid-tarif

channel-type.energidataservice.datahub-price.label = Datahub Price
channel-type.energidataservice.datahub-price.description = Datahub price.
channel-type.energidataservice.hourly-prices.label = Hourly Prices
channel-type.energidataservice.hourly-prices.description = JSON array with hourly prices from 24 hours ago and onward.
channel-type.energidataservice.spot-price.label = Spot Price
channel-type.energidataservice.spot-price.description = Spot price.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
<label>Reduced Electricity Tax</label>
<description>Reduced electricity tax in DKK per kWh. For electric heating customers only.</description>
</channel>
<channel id="hourly-prices" typeId="hourly-prices"/>
</channels>
</channel-group-type>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,4 @@
<config-description-ref uri="channel-type:energidataservice:datahub-price"/>
</channel-type>

<channel-type id="hourly-prices" advanced="true">
<item-type>String</item-type>
<label>Hourly Prices</label>
<description>JSON array with hourly prices from 24 hours ago and onward.</description>
<category>Price</category>
<state readOnly="true"></state>
</channel-type>

</thing:thing-descriptions>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</channel-groups>

<properties>
<property name="thingTypeVersion">3</property>
<property name="thingTypeVersion">4</property>
</properties>

<config-description-ref uri="thing-type:energidataservice:service"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
</update-channel>
</instruction-set>

<instruction-set targetVersion="4">
<remove-channel id="hourly-prices" groupIds="electricity"/>
</instruction-set>

</thing-type>

</update:update-descriptions>

0 comments on commit 9afbe0b

Please sign in to comment.