Introduce a trigger channel to announce the availability of day-ahead prices (#16704)

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
Jacob Laursen 2024-05-10 17:09:27 +02:00 committed by GitHub
parent 4fbe464a51
commit fc68df7a6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 74 additions and 4 deletions

View File

@ -170,6 +170,14 @@ A persistence configuration is required for this channel.
Please note that the CO₂ emission channels only apply to Denmark.
These channels will not be updated when the configured price area is not DK1 or DK2.
#### Trigger Channels
Advanced channel `event` can trigger the following events:
| Event | Description |
|----------------------|--------------------------------|
| DAY_AHEAD_AVAILABLE | Day-ahead prices are available |
## Thing Actions
Thing actions can be used to perform calculations as well as import prices directly into rules without relying on persistence.
@ -561,3 +569,36 @@ console.log("Spot price two hours from now: " + price);
:::
::::
### Trigger Channel Example
:::: tabs
::: tab DSL
```javascript
rule "Day-ahead event"
when
Channel 'energidataservice:service:energidataservice:electricity#event' triggered 'DAY_AHEAD_AVAILABLE'
then
logInfo("Day-ahead", "Day-ahead prices for the next day are now available")
end
```
:::
::: tab JavaScript
```javascript
rules.when()
.channel('energidataservice:service:energidataservice:electricity#event').triggered('DAY_AHEAD_AVAILABLE')
.then(event =>
{
console.log('Day-ahead prices for the next day are now available');
})
.build("Day-ahead event");
```
:::
::::

View File

@ -56,6 +56,7 @@ public class EnergiDataServiceBindingConstants {
+ ChannelUID.CHANNEL_GROUP_SEPARATOR + "co2-emission-prognosis";
public static final String CHANNEL_CO2_EMISSION_REALTIME = CHANNEL_GROUP_ELECTRICITY
+ ChannelUID.CHANNEL_GROUP_SEPARATOR + "co2-emission-realtime";
public static final String CHANNEL_EVENT = CHANNEL_GROUP_ELECTRICITY + ChannelUID.CHANNEL_GROUP_SEPARATOR + "event";
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,
@ -67,6 +68,9 @@ public class EnergiDataServiceBindingConstants {
public static final String PROPERTY_LAST_CALL = "lastCall";
public static final String PROPERTY_NEXT_CALL = "nextCall";
// List of all events
public static final String EVENT_DAY_AHEAD_AVAILABLE = "DAY_AHEAD_AVAILABLE";
// List of supported currencies
public static final Currency CURRENCY_DKK = Currency.getInstance("DKK");
public static final Currency CURRENCY_EUR = Currency.getInstance("EUR");

View File

@ -239,8 +239,9 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
private void refreshElectricityPrices() {
RetryStrategy retryPolicy;
try {
boolean spotPricesDownloaded = false;
if (isLinked(CHANNEL_SPOT_PRICE)) {
downloadSpotPrices();
spotPricesDownloaded = downloadSpotPrices();
}
for (DatahubTariff datahubTariff : DatahubTariff.values()) {
@ -259,6 +260,9 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
if (numberOfFutureSpotPrices >= 13 || (numberOfFutureSpotPrices == 12
&& now.isAfter(DAILY_REFRESH_TIME_CET.minusHours(1)) && now.isBefore(DAILY_REFRESH_TIME_CET))) {
if (spotPricesDownloaded) {
triggerChannel(CHANNEL_EVENT, EVENT_DAY_AHEAD_AVAILABLE);
}
retryPolicy = RetryPolicyFactory.atFixedTime(DAILY_REFRESH_TIME_CET, NORD_POOL_TIMEZONE);
} else {
logger.warn("Spot prices are not available, retry scheduled (see details in Thing properties)");
@ -287,10 +291,10 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
reschedulePriceRefreshJob(retryPolicy);
}
private void downloadSpotPrices() throws InterruptedException, DataServiceException {
private boolean downloadSpotPrices() throws InterruptedException, DataServiceException {
if (cacheManager.areSpotPricesFullyCached()) {
logger.debug("Cached spot prices still valid, skipping download.");
return;
return false;
}
DateQueryParameter start;
if (cacheManager.areHistoricSpotPricesCached()) {
@ -307,6 +311,7 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
} finally {
updateProperties(properties);
}
return true;
}
private void downloadTariffs(DatahubTariff datahubTariff) throws InterruptedException, DataServiceException {

View File

@ -81,6 +81,8 @@ channel-type.energidataservice.co2-emission.label = CO₂ Emission
channel-type.energidataservice.co2-emission.description = CO₂ emission in g/kWh.
channel-type.energidataservice.datahub-price.label = Datahub Price
channel-type.energidataservice.datahub-price.description = Datahub price.
channel-type.energidataservice.event.label = Event
channel-type.energidataservice.event.description = Event triggered
channel-type.energidataservice.spot-price.label = Spot Price
channel-type.energidataservice.spot-price.description = Spot price.

View File

@ -40,6 +40,7 @@
<label>CO₂ Emission Realtime</label>
<description>Near up-to-date history for CO₂ emission from electricity consumed in Denmark in g/kWh.</description>
</channel>
<channel id="event" typeId="event"/>
</channels>
</channel-group-type>

View File

@ -29,4 +29,15 @@
<state readOnly="true" pattern="%.1f %unit%"></state>
</channel-type>
<channel-type id="event" advanced="true">
<kind>trigger</kind>
<label>Event</label>
<description>Event triggered</description>
<event>
<options>
<option value="DAY_AHEAD_AVAILABLE">Day-ahead prices are available</option>
</options>
</event>
</channel-type>
</thing:thing-descriptions>

View File

@ -14,7 +14,7 @@
</channel-groups>
<properties>
<property name="thingTypeVersion">5</property>
<property name="thingTypeVersion">6</property>
</properties>
<config-description-ref uri="thing-type:energidataservice:service"/>

View File

@ -78,6 +78,12 @@
</add-channel>
</instruction-set>
<instruction-set targetVersion="6">
<add-channel id="event" groupIds="electricity">
<type>energidataservice:event</type>
</add-channel>
</instruction-set>
</thing-type>
</update:update-descriptions>