mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-02-04 11:24:10 +01:00
Remove obsoleted advanced channel hourly-prices (#16190)
Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
parent
daea030c11
commit
9afbe0b4f7
@ -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 |
|
| transmission-grid-tariff | Number:EnergyPrice | Transmission grid tariff in DKK per kWh | no |
|
||||||
| electricity-tax | Number:EnergyPrice | Electricity tax 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 |
|
| 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.
|
_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.
|
Instead, create a group item with `SUM` as aggregate function and add the individual price items as children.
|
||||||
@ -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.
|
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.
|
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
|
||||||
|
|
||||||
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.
|
Thing actions can be used to perform calculations as well as import prices directly into rules without relying on persistence.
|
||||||
This is more convenient, much faster, and provides automatic summation of the price components of interest.
|
This is convenient, fast, and provides automatic summation of the price components of interest.
|
||||||
|
|
||||||
Actions use cached data for performing operations.
|
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.
|
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.
|
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.
|
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`
|
### `calculateCheapestPeriod`
|
||||||
|
|
||||||
@ -342,7 +309,7 @@ The parameter `priceComponents` is a case-insensitive comma-separated list of pr
|
|||||||
These components can be requested:
|
These components can be requested:
|
||||||
|
|
||||||
| Price component | Description |
|
| Price component | Description |
|
||||||
|------------------------|-------------------------|
|
|------------------------|--------------------------|
|
||||||
| SpotPrice | Spot price |
|
| SpotPrice | Spot price |
|
||||||
| GridTariff | Grid tariff |
|
| GridTariff | Grid tariff |
|
||||||
| SystemTariff | System tariff |
|
| SystemTariff | System tariff |
|
||||||
@ -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 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 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"] }
|
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
|
### Thing Actions Example
|
||||||
|
|
||||||
:::: tabs
|
:::: tabs
|
||||||
@ -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);
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::::
|
||||||
|
@ -52,12 +52,10 @@ public class EnergiDataServiceBindingConstants {
|
|||||||
+ ChannelUID.CHANNEL_GROUP_SEPARATOR + "reduced-electricity-tax";
|
+ ChannelUID.CHANNEL_GROUP_SEPARATOR + "reduced-electricity-tax";
|
||||||
public static final String CHANNEL_TRANSMISSION_GRID_TARIFF = CHANNEL_GROUP_ELECTRICITY
|
public static final String CHANNEL_TRANSMISSION_GRID_TARIFF = CHANNEL_GROUP_ELECTRICITY
|
||||||
+ ChannelUID.CHANNEL_GROUP_SEPARATOR + "transmission-grid-tariff";
|
+ 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,
|
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_SYSTEM_TARIFF, CHANNEL_TRANSMISSION_GRID_TARIFF, CHANNEL_ELECTRICITY_TAX,
|
||||||
CHANNEL_REDUCED_ELECTRICITY_TAX, CHANNEL_HOURLY_PRICES);
|
CHANNEL_REDUCED_ELECTRICITY_TAX);
|
||||||
|
|
||||||
// List of all properties
|
// List of all properties
|
||||||
public static final String PROPERTY_REMAINING_CALLS = "remainingCalls";
|
public static final String PROPERTY_REMAINING_CALLS = "remainingCalls";
|
||||||
|
@ -60,7 +60,6 @@ import org.openhab.binding.energidataservice.internal.retry.RetryStrategy;
|
|||||||
import org.openhab.core.i18n.TimeZoneProvider;
|
import org.openhab.core.i18n.TimeZoneProvider;
|
||||||
import org.openhab.core.library.types.DecimalType;
|
import org.openhab.core.library.types.DecimalType;
|
||||||
import org.openhab.core.library.types.QuantityType;
|
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.library.unit.CurrencyUnits;
|
||||||
import org.openhab.core.thing.Channel;
|
import org.openhab.core.thing.Channel;
|
||||||
import org.openhab.core.thing.ChannelUID;
|
import org.openhab.core.thing.ChannelUID;
|
||||||
@ -77,8 +76,6 @@ import org.openhab.core.types.UnDefType;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link EnergiDataServiceHandler} is responsible for handling commands, which are
|
* The {@link EnergiDataServiceHandler} is responsible for handling commands, which are
|
||||||
* sent to one of the channels.
|
* sent to one of the channels.
|
||||||
@ -92,19 +89,12 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
|
|||||||
private final TimeZoneProvider timeZoneProvider;
|
private final TimeZoneProvider timeZoneProvider;
|
||||||
private final ApiController apiController;
|
private final ApiController apiController;
|
||||||
private final CacheManager cacheManager;
|
private final CacheManager cacheManager;
|
||||||
private final Gson gson = new Gson();
|
|
||||||
|
|
||||||
private EnergiDataServiceConfiguration config;
|
private EnergiDataServiceConfiguration config;
|
||||||
private RetryStrategy retryPolicy = RetryPolicyFactory.initial();
|
private RetryStrategy retryPolicy = RetryPolicyFactory.initial();
|
||||||
private @Nullable ScheduledFuture<?> refreshFuture;
|
private @Nullable ScheduledFuture<?> refreshFuture;
|
||||||
private @Nullable ScheduledFuture<?> priceUpdateFuture;
|
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) {
|
public EnergiDataServiceHandler(Thing thing, HttpClient httpClient, TimeZoneProvider timeZoneProvider) {
|
||||||
super(thing);
|
super(thing);
|
||||||
this.timeZoneProvider = timeZoneProvider;
|
this.timeZoneProvider = timeZoneProvider;
|
||||||
@ -177,12 +167,12 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
|
|||||||
private void refreshElectricityPrices() {
|
private void refreshElectricityPrices() {
|
||||||
RetryStrategy retryPolicy;
|
RetryStrategy retryPolicy;
|
||||||
try {
|
try {
|
||||||
if (isLinked(CHANNEL_SPOT_PRICE) || isLinked(CHANNEL_HOURLY_PRICES)) {
|
if (isLinked(CHANNEL_SPOT_PRICE)) {
|
||||||
downloadSpotPrices();
|
downloadSpotPrices();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DatahubTariff datahubTariff : DatahubTariff.values()) {
|
for (DatahubTariff datahubTariff : DatahubTariff.values()) {
|
||||||
if (isLinked(datahubTariff.getChannelId()) || isLinked(CHANNEL_HOURLY_PRICES)) {
|
if (isLinked(datahubTariff.getChannelId())) {
|
||||||
downloadTariffs(datahubTariff);
|
downloadTariffs(datahubTariff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,7 +181,7 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
|
|||||||
updatePrices();
|
updatePrices();
|
||||||
updateTimeSeries();
|
updateTimeSeries();
|
||||||
|
|
||||||
if (isLinked(CHANNEL_SPOT_PRICE) || isLinked(CHANNEL_HOURLY_PRICES)) {
|
if (isLinked(CHANNEL_SPOT_PRICE)) {
|
||||||
if (cacheManager.getNumberOfFutureSpotPrices() < 13) {
|
if (cacheManager.getNumberOfFutureSpotPrices() < 13) {
|
||||||
retryPolicy = RetryPolicyFactory.whenExpectedSpotPriceDataMissing(DAILY_REFRESH_TIME_CET,
|
retryPolicy = RetryPolicyFactory.whenExpectedSpotPriceDataMissing(DAILY_REFRESH_TIME_CET,
|
||||||
NORD_POOL_TIMEZONE);
|
NORD_POOL_TIMEZONE);
|
||||||
@ -315,7 +305,6 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
|
|||||||
updateCurrentSpotPrice();
|
updateCurrentSpotPrice();
|
||||||
Arrays.stream(DatahubTariff.values())
|
Arrays.stream(DatahubTariff.values())
|
||||||
.forEach(tariff -> updateCurrentTariff(tariff.getChannelId(), cacheManager.getTariff(tariff)));
|
.forEach(tariff -> updateCurrentTariff(tariff.getChannelId(), cacheManager.getTariff(tariff)));
|
||||||
updateHourlyPrices();
|
|
||||||
|
|
||||||
reschedulePriceUpdateJob();
|
reschedulePriceUpdateJob();
|
||||||
}
|
}
|
||||||
@ -354,30 +343,6 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
private void updateTimeSeries() {
|
||||||
TimeSeries spotPriceTimeSeries = new TimeSeries(REPLACE);
|
TimeSeries spotPriceTimeSeries = new TimeSeries(REPLACE);
|
||||||
Map<DatahubTariff, TimeSeries> datahubTimeSeriesMap = new HashMap<>();
|
Map<DatahubTariff, TimeSeries> datahubTimeSeriesMap = new HashMap<>();
|
||||||
|
@ -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.label = Datahub Price
|
||||||
channel-type.energidataservice.datahub-price.description = 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.label = Spot Price
|
||||||
channel-type.energidataservice.spot-price.description = Spot price.
|
channel-type.energidataservice.spot-price.description = Spot price.
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
<label>Reduced Electricity Tax</label>
|
<label>Reduced Electricity Tax</label>
|
||||||
<description>Reduced electricity tax in DKK per kWh. For electric heating customers only.</description>
|
<description>Reduced electricity tax in DKK per kWh. For electric heating customers only.</description>
|
||||||
</channel>
|
</channel>
|
||||||
<channel id="hourly-prices" typeId="hourly-prices"/>
|
|
||||||
</channels>
|
</channels>
|
||||||
</channel-group-type>
|
</channel-group-type>
|
||||||
|
|
||||||
|
@ -21,12 +21,4 @@
|
|||||||
<config-description-ref uri="channel-type:energidataservice:datahub-price"/>
|
<config-description-ref uri="channel-type:energidataservice:datahub-price"/>
|
||||||
</channel-type>
|
</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>
|
</thing:thing-descriptions>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
</channel-groups>
|
</channel-groups>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<property name="thingTypeVersion">3</property>
|
<property name="thingTypeVersion">4</property>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<config-description-ref uri="thing-type:energidataservice:service"/>
|
<config-description-ref uri="thing-type:energidataservice:service"/>
|
||||||
|
@ -61,6 +61,10 @@
|
|||||||
</update-channel>
|
</update-channel>
|
||||||
</instruction-set>
|
</instruction-set>
|
||||||
|
|
||||||
|
<instruction-set targetVersion="4">
|
||||||
|
<remove-channel id="hourly-prices" groupIds="electricity"/>
|
||||||
|
</instruction-set>
|
||||||
|
|
||||||
</thing-type>
|
</thing-type>
|
||||||
|
|
||||||
</update:update-descriptions>
|
</update:update-descriptions>
|
||||||
|
Loading…
Reference in New Issue
Block a user