From 4c3b3983988a020deb0d3853b15f0726f15bb0e9 Mon Sep 17 00:00:00 2001 From: Jacob Laursen Date: Sun, 16 Jul 2023 14:36:32 +0200 Subject: [PATCH] Extend and simplify date query offset support (#15246) Fixes #15245 Signed-off-by: Jacob Laursen --- .../README.md | 19 ++++++++---- .../api/DatahubTariffFilterFactory.java | 31 +++++++++---------- .../internal/api/DateQueryParameter.java | 14 ++++++++- .../config/DatahubPriceConfiguration.java | 20 ++++++++++-- .../handler/EnergiDataServiceHandler.java | 8 +++-- .../main/resources/OH-INF/config/config.xml | 5 +++ .../OH-INF/i18n/energidataservice.properties | 2 ++ 7 files changed, 71 insertions(+), 28 deletions(-) diff --git a/bundles/org.openhab.binding.energidataservice/README.md b/bundles/org.openhab.binding.energidataservice/README.md index bdae74c8b..00c603d3e 100644 --- a/bundles/org.openhab.binding.energidataservice/README.md +++ b/bundles/org.openhab.binding.energidataservice/README.md @@ -71,11 +71,12 @@ The tariffs are downloaded using pre-configured filters for the different [Grid If your company is not in the list, or the filters are not working, they can be manually overridden. To override filters, the channel `net-tariff` has the following configuration parameters: -| Name | Type | Description | Default | Required | Advanced | -|-----------------|---------|----------------------------------------------------------------------------------------------------------------------------|---------|----------|----------| -| chargeTypeCodes | text | Comma-separated list of charge type codes | | no | yes | -| notes | text | Comma-separated list of notes | | no | yes | -| start | text | Query start date parameter expressed as either YYYY-MM-DD or dynamically as one of StartOfDay, StartOfMonth or StartOfYear | | no | yes | +| Name | Type | Description | Default | Required | Advanced | +|-----------------|---------|----------------------------------------------------------------------------------------------------------------------------------|---------|----------|----------| +| chargeTypeCodes | text | Comma-separated list of charge type codes | | no | yes | +| notes | text | Comma-separated list of notes | | no | yes | +| start | text | Query start date parameter expressed as either YYYY-MM-DD or dynamically as one of `StartOfDay`, `StartOfMonth` or `StartOfYear` | | no | yes | +| offset | text | Query start date offset expressed as an ISO 8601 duration | | no | yes | The parameters `chargeTypeCodes` and `notes` are logically combined with "AND", so if only one parameter is needed for the filter, only provide this parameter and leave the other one empty. Using any of these parameters will override the pre-configured filter entirely. @@ -83,6 +84,10 @@ Using any of these parameters will override the pre-configured filter entirely. The parameter `start` can be used independently to override the query start date parameter. If used while leaving `chargeTypeCodes` and `notes` empty, only the date will be overridden. +The parameter `offset` can be used in combination with `start` to provide an offset to a dynamic start date parameter, i.e. `StartOfDay`, `StartOfMonth` or `StartOfYear`. +The needed amount of historic hours is automatically taken into consideration. +This parameter is ignored when start date is supplied as YYYY-MM-DD. + Determining the right filters can be tricky, so if in doubt ask in the community forum. See also [Datahub Price List](https://www.energidataservice.dk/tso-electricity/DatahubPricelist). @@ -97,8 +102,10 @@ _N1:_ _Nord Energi Net:_ | Parameter | Value | |-----------------|------------| -| chargeTypeCodes | TA031U200 | +| chargeTypeCodes | TAC | | notes | Nettarif C | +| start | StartOfDay | +| offset | -P1D | #### Hourly Prices diff --git a/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/api/DatahubTariffFilterFactory.java b/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/api/DatahubTariffFilterFactory.java index f20c46873..31a1f5b86 100644 --- a/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/api/DatahubTariffFilterFactory.java +++ b/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/api/DatahubTariffFilterFactory.java @@ -14,7 +14,6 @@ package org.openhab.binding.energidataservice.internal.api; import static org.openhab.binding.energidataservice.internal.EnergiDataServiceBindingConstants.*; -import java.time.Duration; import java.time.LocalDate; import java.util.Set; @@ -78,21 +77,21 @@ public class DatahubTariffFilterFactory { return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("TCL>100_02")), Set.of(NOTE_NET_TARIFF_C_HOUR)); case GLN_ELEKTRUS: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("6000091")), Set.of(NOTE_NET_TARIFF_C_HOUR), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_ELINORD: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("43300")), Set.of("Transportbetaling, eget net C")); case GLN_ELNET_MIDT: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("T3002")), Set.of(NOTE_NET_TARIFF_C), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_ELNET_KONGERSLEV: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("K_22100")), Set.of(NOTE_NET_TARIFF_C)); case GLN_FLOW_ELNET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("FE2 NT-01")), Set.of(NOTE_NET_TARIFF_C_HOUR), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_HAMMEL_ELFORSYNING_NET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("50001")), Set.of("Overliggende net"), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_HURUP_ELVAERK_NET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("HEV-NT-01")), Set.of(NOTE_NET_TARIFF)); case GLN_IKAST_E1_NET: @@ -105,19 +104,19 @@ public class DatahubTariffFilterFactory { return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("4010")), Set.of(NOTE_NET_TARIFF_C_HOUR)); case GLN_MIDTFYNS_ELFORSYNING: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("TNT15000")), Set.of(NOTE_NET_TARIFF_C_FLEX), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_N1: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("CD"), ChargeTypeCode.of("CD R")), Set.of(), DateQueryParameter.of(N1_CUTOFF_DATE)); case GLN_NETSELSKABET_ELVAERK: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("0NCFF")), Set.of(NOTE_NET_TARIFF_C + " Flex"), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_NKE_ELNET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("94TR_C_ET")), Set.of(NOTE_NET_TARIFF_C_HOUR), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_NORD_ENERGI_NET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("TAC")), Set.of(NOTE_NET_TARIFF_C), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_NORDVESTJYSK_ELFORSYNING_NOE_NET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("Net C")), Set.of(NOTE_NET_TARIFF_C)); case GLN_RADIUS: @@ -125,31 +124,31 @@ public class DatahubTariffFilterFactory { DateQueryParameter.of(RADIUS_CUTOFF_DATE)); case GLN_RAH_NET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("RAH-C")), Set.of(NOTE_NET_TARIFF_C_HOUR), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_RAVDEX: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("NT-C")), Set.of(NOTE_NET_TARIFF_C_HOUR), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_SUNDS_NET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("SEF-NT-05")), Set.of(NOTE_NET_TARIFF_C_FLEX_HOUR), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_TARM_ELVAERK_NET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("TEV-NT-01")), Set.of(NOTE_NET_TARIFF_C)); case GLN_TREFOR_EL_NET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("C")), Set.of(NOTE_NET_TARIFF_C_HOUR), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_TREFOR_EL_NET_OEST: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("46")), Set.of(NOTE_NET_TARIFF_C_HOUR), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_VEKSEL: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("NT-10")), Set.of(NOTE_NET_TARIFF_C_HOUR + " NT-10")); case GLN_VORES_ELNET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("TNT1009")), Set.of(NOTE_NET_TARIFF_C_HOUR), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); case GLN_ZEANET: return new DatahubTariffFilter(Set.of(ChargeTypeCode.of("43110")), Set.of(NOTE_NET_TARIFF_C_HOUR), - DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, Duration.ofDays(-1))); + DateQueryParameter.of(DateQueryParameterType.START_OF_DAY)); default: return new DatahubTariffFilter(Set.of(), Set.of(NOTE_NET_TARIFF_C), DateQueryParameter.of(DateQueryParameterType.START_OF_YEAR)); diff --git a/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/api/DateQueryParameter.java b/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/api/DateQueryParameter.java index 70f996a97..2d39a15cf 100644 --- a/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/api/DateQueryParameter.java +++ b/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/api/DateQueryParameter.java @@ -58,7 +58,7 @@ public class DateQueryParameter { DateQueryParameterType dateType = this.dateType; if (dateType != null) { Duration offset = this.offset; - if (offset == null) { + if (offset == null || offset.isZero()) { return dateType.toString(); } else { return dateType.toString() @@ -84,6 +84,18 @@ public class DateQueryParameter { } } + public static DateQueryParameter of(DateQueryParameter parameter, Duration offset) { + DateQueryParameterType parameterType = parameter.dateType; + if (parameterType == null) { + return parameter; + } + Duration parameterOffset = parameter.offset; + if (parameterOffset == null || parameterOffset.isZero()) { + return of(parameterType, offset); + } + return of(parameterType, parameterOffset.plus(offset)); + } + public static DateQueryParameter of(DateQueryParameterType dateType) { return new DateQueryParameter(dateType); } diff --git a/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/config/DatahubPriceConfiguration.java b/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/config/DatahubPriceConfiguration.java index 8a59da81d..fa63dc662 100644 --- a/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/config/DatahubPriceConfiguration.java +++ b/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/config/DatahubPriceConfiguration.java @@ -12,6 +12,7 @@ */ package org.openhab.binding.energidataservice.internal.config; +import java.time.Duration; import java.time.LocalDate; import java.time.format.DateTimeParseException; import java.util.Arrays; @@ -47,6 +48,11 @@ public class DatahubPriceConfiguration { */ public String start = ""; + /** + * Query start date offset expressed as an ISO 8601 duration. + */ + public String offset = ""; + /** * Check if any filter values are provided. * @@ -85,14 +91,22 @@ public class DatahubPriceConfiguration { if (start.isBlank()) { return DateQueryParameter.EMPTY; } + Duration durationOffset = Duration.ZERO; + if (!offset.isBlank()) { + try { + durationOffset = Duration.parse(offset); + } catch (DateTimeParseException e) { + return null; + } + } if (start.equals(DateQueryParameterType.START_OF_DAY.toString())) { - return DateQueryParameter.of(DateQueryParameterType.START_OF_DAY); + return DateQueryParameter.of(DateQueryParameterType.START_OF_DAY, durationOffset); } if (start.equals(DateQueryParameterType.START_OF_MONTH.toString())) { - return DateQueryParameter.of(DateQueryParameterType.START_OF_MONTH); + return DateQueryParameter.of(DateQueryParameterType.START_OF_MONTH, durationOffset); } if (start.equals(DateQueryParameterType.START_OF_YEAR.toString())) { - return DateQueryParameter.of(DateQueryParameterType.START_OF_YEAR); + return DateQueryParameter.of(DateQueryParameterType.START_OF_YEAR, durationOffset); } try { return DateQueryParameter.of(LocalDate.parse(start)); diff --git a/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/handler/EnergiDataServiceHandler.java b/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/handler/EnergiDataServiceHandler.java index 16bffcf8d..970d8a1da 100644 --- a/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/handler/EnergiDataServiceHandler.java +++ b/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/handler/EnergiDataServiceHandler.java @@ -246,7 +246,10 @@ public class EnergiDataServiceHandler extends BaseThingHandler { logger.debug("Cached net tariffs still valid, skipping download."); cacheManager.updateNetTariffs(); } else { - cacheManager.putNetTariffs(downloadPriceLists(config.getGridCompanyGLN(), getNetTariffFilter())); + DatahubTariffFilter filter = getNetTariffFilter(); + cacheManager.putNetTariffs(downloadPriceLists(config.getGridCompanyGLN(), + new DatahubTariffFilter(filter, DateQueryParameter.of(filter.getDateQueryParameter(), + Duration.ofHours(-CacheManager.NUMBER_OF_HISTORIC_HOURS))))); } } @@ -317,7 +320,8 @@ public class EnergiDataServiceHandler extends BaseThingHandler { DateQueryParameter start = datahubPriceConfiguration.getStart(); if (start == null) { - logger.warn("Invalid channel configuration parameter 'start': {}", datahubPriceConfiguration.start); + logger.warn("Invalid channel configuration parameter 'start' or 'offset': {} (offset: {})", + datahubPriceConfiguration.start, datahubPriceConfiguration.offset); return DatahubTariffFilterFactory.getNetTariffByGLN(config.gridCompanyGLN); } diff --git a/bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/config/config.xml index 77d3dfe3c..02791241b 100644 --- a/bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/config/config.xml @@ -89,6 +89,11 @@ true + + + Query start date offset expressed as an ISO 8601 duration. + true + diff --git a/bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/i18n/energidataservice.properties b/bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/i18n/energidataservice.properties index cd752ac37..70e7d27d6 100644 --- a/bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/i18n/energidataservice.properties +++ b/bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/i18n/energidataservice.properties @@ -81,6 +81,8 @@ channel-type.config.energidataservice.datahub-price.chargeTypeCodes.label = Char channel-type.config.energidataservice.datahub-price.chargeTypeCodes.description = Comma-separated list of charge type codes. channel-type.config.energidataservice.datahub-price.notes.label = Note Filters channel-type.config.energidataservice.datahub-price.notes.description = Comma-separated list of notes. +channel-type.config.energidataservice.datahub-price.offset.label = Date Offset +channel-type.config.energidataservice.datahub-price.offset.description = Query start date offset expressed as an ISO 8601 duration. channel-type.config.energidataservice.datahub-price.start.label = Query Start Date channel-type.config.energidataservice.datahub-price.start.description = Query start date parameter expressed as either YYYY-MM-DD or dynamically as one of StartOfDay, StartOfMonth or StartOfYear. channel-type.config.energidataservice.datahub-price.start.option.StartOfDay = Start of day