]> git.basschouten.com Git - openhab-addons.git/commitdiff
Add new channel for reduced electricity tax (#15636)
authorJacob Laursen <jacob-github@vindvejr.dk>
Wed, 18 Oct 2023 06:25:00 +0000 (08:25 +0200)
committerGitHub <noreply@github.com>
Wed, 18 Oct 2023 06:25:00 +0000 (08:25 +0200)
Resolves #15635

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
17 files changed:
bundles/org.openhab.binding.energidataservice/README.md
bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/DatahubTariff.java
bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/EnergiDataServiceBindingConstants.java
bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/action/EnergiDataServiceActions.java
bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/api/DatahubTariffFilterFactory.java
bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/config/EnergiDataServiceConfiguration.java
bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/handler/EnergiDataServiceHandler.java
bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/config/config.xml
bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/i18n/energidataservice.properties
bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/thing/channel-groups.xml
bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/thing/thing-service.xml
bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/update/instructions.xml [new file with mode: 0644]
bundles/org.openhab.binding.energidataservice/src/test/java/org/openhab/binding/energidataservice/internal/action/EnergiDataServiceActionsTest.java
bundles/org.openhab.binding.energidataservice/src/test/resources/org/openhab/binding/energidataservice/internal/action/ElectricityTaxes.json
bundles/org.openhab.binding.energidataservice/src/test/resources/org/openhab/binding/energidataservice/internal/action/NetTariffs.json
bundles/org.openhab.binding.energidataservice/src/test/resources/org/openhab/binding/energidataservice/internal/action/ReducedElectricityTaxes.json [new file with mode: 0644]
bundles/org.openhab.binding.energidataservice/src/test/resources/org/openhab/binding/energidataservice/internal/action/SpotPrices20231003.json [new file with mode: 0644]

index 00c603d3ecbdc9ae9a6316d9d7670c3abaa9f2e9..7f43adf2cf5a2e3bc76c373bdd2f2e0ce19f587c 100644 (file)
@@ -12,12 +12,13 @@ All channels are available for thing type `service`.
 
 ### `service` Thing Configuration
 
-| Name           | Type    | Description                                       | Default       | Required |
-|----------------|---------|---------------------------------------------------|---------------|----------|
-| priceArea      | text    | Price area for spot prices (same as bidding zone) |               | yes      |
-| currencyCode   | text    | Currency code in which to obtain spot prices      | DKK           | no       |
-| gridCompanyGLN | integer | Global Location Number of the Grid Company        |               | no       |
-| energinetGLN   | integer | Global Location Number of Energinet               | 5790000432752 | no       |
+| Name                  | Type    | Description                                                          | Default       | Required |
+|-----------------------|---------|----------------------------------------------------------------------|---------------|----------|
+| priceArea             | text    | Price area for spot prices (same as bidding zone)                    |               | yes      |
+| currencyCode          | text    | Currency code in which to obtain spot prices                         | DKK           | no       |
+| gridCompanyGLN        | integer | Global Location Number of the Grid Company                           |               | no       |
+| energinetGLN          | integer | Global Location Number of Energinet                                  | 5790000432752 | no       |
+| reducedElectricityTax | boolean | Reduced electricity tax applies. For electric heating customers only | false         | no       |
 
 #### Global Location Number of the Grid Company
 
@@ -35,6 +36,13 @@ To obtain the Global Location Number of your grid company:
 - In column **Owner** you can find the GLN ("Global Location Number").
 - Most rows will have this **Owner**. If in doubt, try to look for rows __not__ having 5790000432752 as owner.
 
+#### Reduced electricity tax applies
+
+For customers using electricity for heating, a reduced electricity tax rate may apply after consuming the first 4000 kWh within a year.
+When you are entitled to reduced electricity tax, this option should be set.
+This will ensure that thing action calculations use the reduced electricity tax rate when price elements are not explicitly provided.
+It will not impact channels, see [Electricity Tax](#electricity-tax) for further information.
+
 ## Channels
 
 ### Channel Group `electricity`
@@ -45,6 +53,7 @@ To obtain the Global Location Number of your grid company:
 | net-tariff              | Number | Current net tariff in DKK per kWh. Only available when `gridCompanyGLN` is configured | no       |
 | system-tariff           | Number | Current system tariff in DKK per kWh                                                  | no       |
 | electricity-tax         | Number | Current electricity tax in DKK per kWh                                                | no       |
+| reduced-electricity-tax | Number | Current reduced electricity tax in DKK per kWh. For electric heating customers only   | no       |
 | transmission-net-tariff | Number | Current transmission net tariff in DKK per kWh                                        | no       |
 | hourly-prices           | String | JSON array with hourly prices from 24 hours ago and onward                            | yes      |
 
@@ -56,6 +65,9 @@ This has the following advantages:
 - An additional item containing the kWh fee from your electricity supplier can be added also.
 - Spot price can be configured in EUR while tariffs are in DKK.
 
+If you want electricity tax included in your total price, please add either `electricity-tax` or `reduced-electricity-tax` to the group - depending on which one applies.
+See [Electricity Tax](#electricity-tax) for further information.
+
 #### Value-Added Tax
 
 VAT is not included in any of the prices.
@@ -107,6 +119,15 @@ _Nord Energi Net:_
 | start           | StartOfDay |
 | offset          | -P1D       |
 
+#### Electricity Tax
+
+The standard channel for electricity tax is `electricity-tax`.
+For customers using electricity for heating, a reduced electricity tax rate may apply (see [Reduced electricity tax applies](#reduced-electricity-tax-applies)).
+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:
@@ -114,22 +135,24 @@ The format of the `hourly-prices` JSON array is as follows:
 ```json
 [
        {
-               "hourStart": "2023-01-24T15:00:00Z",
-               "spotPrice": 1.67076001,
+               "hourStart": "2023-09-19T18:00:00Z",
+               "spotPrice": 0.0,
                "spotPriceCurrency": "DKK",
-               "netTariff": 0.432225,
-               "systemTariff": 0.054000,
-               "electricityTax": 0.008000,
-               "transmissionNetTariff": 0.058000
+               "netTariff": 0.0,
+               "systemTariff": 0.054,
+               "electricityTax": 0.697,
+               "reducedElectricityTax": 0.008,
+               "transmissionNetTariff": 0.058
        },
        {
-               "hourStart": "2023-01-24T16:00:00Z",
-               "spotPrice": 1.859880005,
+               "hourStart": "2023-09-19T19:00:00Z",
+               "spotPrice": -0.00052,
                "spotPriceCurrency": "DKK",
-               "netTariff": 1.05619,
-               "systemTariff": 0.054000,
-               "electricityTax": 0.008000,
-               "transmissionNetTariff": 0.058000
+               "netTariff": 0.0,
+               "systemTariff": 0.054,
+               "electricityTax": 0.697,
+               "reducedElectricityTax": 0.008,
+               "transmissionNetTariff": 0.058
        }
 ]
 ```
@@ -310,14 +333,17 @@ These elements can be requested:
 | NetTariff             | Net tariff              |
 | SystemTariff          | System tariff           |
 | ElectricityTax        | Electricity tax         |
+| ReducedElectricityTax | Reduced electricity tax |
 | TransmissionNetTariff | Transmission net tariff |
 
 Using `null` as parameter returns the total prices including all price elements.
+If **Reduced Electricity Tax** is set in Thing configuration, `ElectricityTax` will be excluded, otherwise `ReducedElectricityTax`.
+This logic ensures consistent and comparable results not affected by artifical changes in the rate for electricity tax two times per year.
 
 Example:
 
 ```javascript
-var priceMap = actions.getPrices("SpotPrice,NetTariff");
+var priceMap = actions.getPrices("SpotPrice,NetTariff")
 ```
 
 ## Full Example
index fb257d006281a4a8b1ba7ffb00e1d7d3b0eee88e..b1e360f53c648188c8b0da9eaa6f294f7909b001 100644 (file)
@@ -26,6 +26,7 @@ public enum DatahubTariff {
     NET_TARIFF(CHANNEL_NET_TARIFF),
     SYSTEM_TARIFF(CHANNEL_SYSTEM_TARIFF),
     ELECTRICITY_TAX(CHANNEL_ELECTRICITY_TAX),
+    REDUCED_ELECTRICITY_TAX(CHANNEL_REDUCED_ELECTRICITY_TAX),
     TRANSMISSION_NET_TARIFF(CHANNEL_TRANSMISSION_NET_TARIFF);
 
     String channelId;
index aa828627a98f0bd7c587138906f2bc86fc314bb6..210b133adb074a580ffd7ced21474658f7094b3e 100644 (file)
@@ -48,13 +48,16 @@ public class EnergiDataServiceBindingConstants {
             + "system-tariff";
     public static final String CHANNEL_ELECTRICITY_TAX = CHANNEL_GROUP_ELECTRICITY + ChannelUID.CHANNEL_GROUP_SEPARATOR
             + "electricity-tax";
+    public static final String CHANNEL_REDUCED_ELECTRICITY_TAX = CHANNEL_GROUP_ELECTRICITY
+            + ChannelUID.CHANNEL_GROUP_SEPARATOR + "reduced-electricity-tax";
     public static final String CHANNEL_TRANSMISSION_NET_TARIFF = CHANNEL_GROUP_ELECTRICITY
             + ChannelUID.CHANNEL_GROUP_SEPARATOR + "transmission-net-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_NET_TARIFF,
-            CHANNEL_SYSTEM_TARIFF, CHANNEL_ELECTRICITY_TAX, CHANNEL_TRANSMISSION_NET_TARIFF, CHANNEL_HOURLY_PRICES);
+            CHANNEL_SYSTEM_TARIFF, CHANNEL_ELECTRICITY_TAX, CHANNEL_REDUCED_ELECTRICITY_TAX,
+            CHANNEL_TRANSMISSION_NET_TARIFF, CHANNEL_HOURLY_PRICES);
 
     // List of all properties
     public static final String PROPERTY_REMAINING_CALLS = "remainingCalls";
index 52cba2cc14b37a4c0be90114b64a4537c9b64fd3..c35cbed206ddd3f2281c94df24fedc7b77377514 100644 (file)
@@ -62,19 +62,22 @@ public class EnergiDataServiceActions implements ThingActions {
     private @Nullable EnergiDataServiceHandler handler;
 
     private enum PriceElement {
-        SPOT_PRICE("spotprice"),
-        NET_TARIFF("nettariff"),
-        SYSTEM_TARIFF("systemtariff"),
-        ELECTRICITY_TAX("electricitytax"),
-        TRANSMISSION_NET_TARIFF("transmissionnettariff");
+        SPOT_PRICE("spotprice", null),
+        NET_TARIFF("nettariff", DatahubTariff.NET_TARIFF),
+        SYSTEM_TARIFF("systemtariff", DatahubTariff.SYSTEM_TARIFF),
+        ELECTRICITY_TAX("electricitytax", DatahubTariff.ELECTRICITY_TAX),
+        REDUCED_ELECTRICITY_TAX("reducedelectricitytax", DatahubTariff.REDUCED_ELECTRICITY_TAX),
+        TRANSMISSION_NET_TARIFF("transmissionnettariff", DatahubTariff.TRANSMISSION_NET_TARIFF);
 
         private static final Map<String, PriceElement> NAME_MAP = Stream.of(values())
                 .collect(Collectors.toMap(PriceElement::toString, Function.identity()));
 
         private String name;
+        private @Nullable DatahubTariff datahubTariff;
 
-        private PriceElement(String name) {
+        private PriceElement(String name, @Nullable DatahubTariff datahubTariff) {
             this.name = name;
+            this.datahubTariff = datahubTariff;
         }
 
         @Override
@@ -90,11 +93,26 @@ public class EnergiDataServiceActions implements ThingActions {
             }
             return myEnum;
         }
+
+        public @Nullable DatahubTariff getDatahubTariff() {
+            return datahubTariff;
+        }
     }
 
     @RuleAction(label = "@text/action.get-prices.label", description = "@text/action.get-prices.description")
     public @ActionOutput(name = "prices", type = "java.util.Map<java.time.Instant, java.math.BigDecimal>") Map<Instant, BigDecimal> getPrices() {
-        return getPrices(Arrays.stream(PriceElement.values()).collect(Collectors.toSet()));
+        EnergiDataServiceHandler handler = this.handler;
+        if (handler == null) {
+            logger.warn("EnergiDataServiceActions ThingHandler is null.");
+            return Map.of();
+        }
+
+        boolean isReducedElectricityTax = handler.isReducedElectricityTax();
+
+        return getPrices(Arrays.stream(PriceElement.values())
+                .filter(element -> element != (isReducedElectricityTax ? PriceElement.ELECTRICITY_TAX
+                        : PriceElement.REDUCED_ELECTRICITY_TAX))
+                .collect(Collectors.toSet()));
     }
 
     @RuleAction(label = "@text/action.get-prices.label", description = "@text/action.get-prices.description")
@@ -236,25 +254,16 @@ public class EnergiDataServiceActions implements ThingActions {
             prices = new HashMap<>();
         }
 
-        if (priceElements.contains(PriceElement.NET_TARIFF)) {
-            Map<Instant, BigDecimal> netTariffMap = handler.getTariffs(DatahubTariff.NET_TARIFF);
-            mergeMaps(prices, netTariffMap, !spotPricesRequired);
-        }
-
-        if (priceElements.contains(PriceElement.SYSTEM_TARIFF)) {
-            Map<Instant, BigDecimal> systemTariffMap = handler.getTariffs(DatahubTariff.SYSTEM_TARIFF);
-            mergeMaps(prices, systemTariffMap, !spotPricesRequired);
-        }
-
-        if (priceElements.contains(PriceElement.ELECTRICITY_TAX)) {
-            Map<Instant, BigDecimal> electricityTaxMap = handler.getTariffs(DatahubTariff.ELECTRICITY_TAX);
-            mergeMaps(prices, electricityTaxMap, !spotPricesRequired);
-        }
+        for (PriceElement priceElement : PriceElement.values()) {
+            DatahubTariff datahubTariff = priceElement.getDatahubTariff();
+            if (datahubTariff == null) {
+                continue;
+            }
 
-        if (priceElements.contains(PriceElement.TRANSMISSION_NET_TARIFF)) {
-            Map<Instant, BigDecimal> transmissionNetTariffMap = handler
-                    .getTariffs(DatahubTariff.TRANSMISSION_NET_TARIFF);
-            mergeMaps(prices, transmissionNetTariffMap, !spotPricesRequired);
+            if (priceElements.contains(priceElement)) {
+                Map<Instant, BigDecimal> tariffMap = handler.getTariffs(datahubTariff);
+                mergeMaps(prices, tariffMap, !spotPricesRequired);
+            }
         }
 
         return prices;
index a79ca9ab5e9dc36a5b28ead229b8a85bd2218916..0c320f0e4ed2f17e5e179844385a0e84d1f6bcef 100644 (file)
@@ -64,6 +64,7 @@ public class DatahubTariffFilterFactory {
     private static final String NOTE_NET_TARIFF_C_FLEX_HOUR = NOTE_NET_TARIFF_C_FLEX + " - time";
     private static final String NOTE_SYSTEM_TARIFF = "Systemtarif";
     private static final String NOTE_ELECTRICITY_TAX = "Elafgift";
+    private static final String NOTE_REDUCED_ELECTRICITY_TAX = "Reduceret elafgift";
     private static final String NOTE_TRANSMISSION_NET_TARIFF = "Transmissions nettarif";
 
     public static final LocalDate N1_CUTOFF_DATE = LocalDate.of(2023, 1, 1);
@@ -171,6 +172,11 @@ public class DatahubTariffFilterFactory {
                 DateQueryParameter.of(ENERGINET_CUTOFF_DATE));
     }
 
+    public static DatahubTariffFilter getReducedElectricityTax() {
+        return new DatahubTariffFilter(Set.of(), Set.of(NOTE_REDUCED_ELECTRICITY_TAX),
+                DateQueryParameter.of(LocalDate.of(2021, 2, 1)));
+    }
+
     public static DatahubTariffFilter getTransmissionNetTariff() {
         return new DatahubTariffFilter(Set.of(), Set.of(NOTE_TRANSMISSION_NET_TARIFF),
                 DateQueryParameter.of(ENERGINET_CUTOFF_DATE));
index 70cf0b45df7d9166f398460554312fb6de66253a..c02816cd9e39b7d861db026072ddbe82d7d68729 100644 (file)
@@ -46,6 +46,12 @@ public class EnergiDataServiceConfiguration {
      */
     public String energinetGLN = "5790000432752";
 
+    /**
+     * Reduced electricity tax applies.
+     * For electric heating customers only.
+     */
+    public boolean reducedElectricityTax;
+
     /**
      * Get {@link Currency} representing the configured currency code.
      * 
index 94a4f430eba6df7b1f058bedeea39112e7eb33ea..3241685f3d9c3d8b141c247a06e340c9476a80f0 100644 (file)
@@ -93,7 +93,7 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
 
     private record Price(String hourStart, BigDecimal spotPrice, String spotPriceCurrency,
             @Nullable BigDecimal netTariff, @Nullable BigDecimal systemTariff, @Nullable BigDecimal electricityTax,
-            @Nullable BigDecimal transmissionNetTariff) {
+            @Nullable BigDecimal reducedElectricityTax, @Nullable BigDecimal transmissionNetTariff) {
     }
 
     public EnergiDataServiceHandler(Thing thing, HttpClient httpClient, TimeZoneProvider timeZoneProvider) {
@@ -246,6 +246,7 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
                 case NET_TARIFF -> getNetTariffFilter();
                 case SYSTEM_TARIFF -> DatahubTariffFilterFactory.getSystemTariff();
                 case ELECTRICITY_TAX -> DatahubTariffFilterFactory.getElectricityTax();
+                case REDUCED_ELECTRICITY_TAX -> DatahubTariffFilterFactory.getReducedElectricityTax();
                 case TRANSMISSION_NET_TARIFF -> DatahubTariffFilterFactory.getTransmissionNetTariff();
             };
             cacheManager.putTariffs(datahubTariff, downloadPriceLists(globalLocationNumber, filter));
@@ -339,9 +340,10 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
             BigDecimal netTariff = cacheManager.getTariff(DatahubTariff.NET_TARIFF, hourStart);
             BigDecimal systemTariff = cacheManager.getTariff(DatahubTariff.SYSTEM_TARIFF, hourStart);
             BigDecimal electricityTax = cacheManager.getTariff(DatahubTariff.ELECTRICITY_TAX, hourStart);
+            BigDecimal reducedElectricityTax = cacheManager.getTariff(DatahubTariff.REDUCED_ELECTRICITY_TAX, hourStart);
             BigDecimal transmissionNetTariff = cacheManager.getTariff(DatahubTariff.TRANSMISSION_NET_TARIFF, hourStart);
             targetPrices[i++] = new Price(hourStart.toString(), sourcePrice.getValue(), config.currencyCode, netTariff,
-                    systemTariff, electricityTax, transmissionNetTariff);
+                    systemTariff, electricityTax, reducedElectricityTax, transmissionNetTariff);
         }
         updateState(CHANNEL_HOURLY_PRICES, new StringType(gson.toJson(targetPrices)));
     }
@@ -399,6 +401,15 @@ public class EnergiDataServiceHandler extends BaseThingHandler {
         return cacheManager.getTariffs(datahubTariff);
     }
 
+    /**
+     * Return whether reduced electricity tax is set in configuration.
+     *
+     * @return true if reduced electricity tax applies
+     */
+    public boolean isReducedElectricityTax() {
+        return config.reducedElectricityTax;
+    }
+
     private void reschedulePriceUpdateJob() {
         ScheduledFuture<?> priceUpdateJob = this.priceUpdateFuture;
         if (priceUpdateJob != null) {
index 208b22d4e452acdb1e37d900d1011d7bb09080b3..c985bcaa6b5c7cfb2fb01dee284519e2d846993a 100644 (file)
                        <advanced>true</advanced>
                        <default>5790000432752</default>
                </parameter>
+               <parameter name="reducedElectricityTax" type="boolean">
+                       <label>Reduced Electricity Tax</label>
+                       <description>Reduced electricity tax applies. For electric heating customers only.</description>
+                       <default>false</default>
+               </parameter>
        </config-description>
 
        <config-description uri="channel-type:energidataservice:datahub-price">
index 420d2314456a909cc1ebc34826960a45633adcea..f63c3a834742d88de781f1ca097ebb85c232adb4 100644 (file)
@@ -51,6 +51,8 @@ thing-type.config.energidataservice.service.priceArea.label = Price Area
 thing-type.config.energidataservice.service.priceArea.description = Price area for spot prices (same as bidding zone).
 thing-type.config.energidataservice.service.priceArea.option.DK1 = West of the Great Belt
 thing-type.config.energidataservice.service.priceArea.option.DK2 = East of the Great Belt
+thing-type.config.energidataservice.service.reducedElectricityTax.label = Reduced Electricity Tax
+thing-type.config.energidataservice.service.reducedElectricityTax.description = Reduced electricity tax applies. For electric heating customers only.
 
 # channel group types
 
@@ -60,6 +62,8 @@ channel-group-type.energidataservice.electricity.channel.electricity-tax.label =
 channel-group-type.energidataservice.electricity.channel.electricity-tax.description = Current electricity tax in DKK per kWh.
 channel-group-type.energidataservice.electricity.channel.net-tariff.label = Net Tariff
 channel-group-type.energidataservice.electricity.channel.net-tariff.description = Current net tariff in DKK per kWh.
+channel-group-type.energidataservice.electricity.channel.reduced-electricity-tax.label = Reduced Electricity Tax
+channel-group-type.energidataservice.electricity.channel.reduced-electricity-tax.description = Current reduced electricity tax in DKK per kWh. For electric heating customers only.
 channel-group-type.energidataservice.electricity.channel.spot-price.label = Spot Price
 channel-group-type.energidataservice.electricity.channel.spot-price.description = Current spot price in DKK or EUR per kWh.
 channel-group-type.energidataservice.electricity.channel.system-tariff.label = System Tariff
index 2a22018260c371c2fe5dd3c344e63694add0d830..c978b03667b3d3f159ca0269ea2952a864180a18 100644 (file)
                                <label>Electricity Tax</label>
                                <description>Current electricity tax in DKK per kWh.</description>
                        </channel>
+                       <channel id="reduced-electricity-tax" typeId="datahub-price">
+                               <label>Reduced Electricity Tax</label>
+                               <description>Current reduced electricity tax in DKK per kWh. For electric heating customers only.</description>
+                       </channel>
                        <channel id="transmission-net-tariff" typeId="datahub-price">
                                <label>Transmission Net Tariff</label>
                                <description>Current transmission net tariff in DKK per kWh.</description>
index c00115a67ddd779ce149e1392a2c5df25e1067cc..b69ef51aa8e1393eaaca1e75df6fb7969361196a 100644 (file)
                        <channel-group id="electricity" typeId="electricity"/>
                </channel-groups>
 
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
+
                <config-description-ref uri="thing-type:energidataservice:service"/>
        </thing-type>
 
diff --git a/bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.energidataservice/src/main/resources/OH-INF/update/instructions.xml
new file mode 100644 (file)
index 0000000..62e2888
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
+
+       <thing-type uid="energidataservice:service">
+
+               <instruction-set targetVersion="1">
+                       <add-channel id="reduced-electricity-tax" groupIds="electricity">
+                               <type>energidataservice:datahub-price</type>
+                               <label>Reduced Electricity Tax</label>
+                               <description>Current reduced electricity tax in DKK per kWh. For electric heating customers only.</description>
+                       </add-channel>
+               </instruction-set>
+
+       </thing-type>
+
+</update:update-descriptions>
index 5679d3d7a4fb523f78820d29a766263c7fbdb31a..70ec701cb6123b929fb822ab6eee27a19365bacd 100644 (file)
@@ -175,9 +175,28 @@ public class EnergiDataServiceActionsTest {
         Map<Instant, BigDecimal> actual = actions.getPrices();
         assertThat(actual.size(), is(35));
         assertThat(actual.get(Instant.parse("2023-02-04T12:00:00Z")), is(equalTo(new BigDecimal("1.545065027"))));
+        assertThat(actual.get(Instant.parse("2023-02-04T15:00:00Z")), is(equalTo(new BigDecimal("1.708765039"))));
         assertThat(actual.get(Instant.parse("2023-02-04T16:00:00Z")), is(equalTo(new BigDecimal("2.443870054"))));
     }
 
+    @Test
+    void getPricesTotalFullElectricityTax() throws IOException {
+        mockCommonDatasets(actions, "SpotPrices20231003.json");
+
+        Map<Instant, BigDecimal> actual = actions.getPrices();
+        assertThat(actual.size(), is(4));
+        assertThat(actual.get(Instant.parse("2023-10-03T20:00:00Z")), is(equalTo(new BigDecimal("0.829059999"))));
+    }
+
+    @Test
+    void getPricesTotalReducedElectricityTax() throws IOException {
+        mockCommonDatasets(actions, "SpotPrices20231003.json", true);
+
+        Map<Instant, BigDecimal> actual = actions.getPrices();
+        assertThat(actual.size(), is(4));
+        assertThat(actual.get(Instant.parse("2023-10-03T20:00:00Z")), is(equalTo(new BigDecimal("0.140059999"))));
+    }
+
     @Test
     void getPricesTotalAllElements() throws IOException {
         mockCommonDatasets(actions);
@@ -374,6 +393,11 @@ public class EnergiDataServiceActionsTest {
     }
 
     private void mockCommonDatasets(EnergiDataServiceActions actions, String spotPricesFilename) throws IOException {
+        mockCommonDatasets(actions, spotPricesFilename, false);
+    }
+
+    private void mockCommonDatasets(EnergiDataServiceActions actions, String spotPricesFilename,
+            boolean isReducedElectricityTax) throws IOException {
         SpotPrice[] spotPriceRecords = getObjectFromJson(spotPricesFilename, SpotPrice[].class);
         Map<Instant, BigDecimal> spotPrices = Arrays.stream(spotPriceRecords)
                 .collect(Collectors.toMap(SpotPrice::hourStart, SpotPrice::spotPrice));
@@ -389,6 +413,9 @@ public class EnergiDataServiceActionsTest {
         datahubRecords = getObjectFromJson("ElectricityTaxes.json", DatahubPricelistRecords.class);
         Map<Instant, BigDecimal> electricityTaxes = priceListParser
                 .toHourly(Arrays.stream(datahubRecords.records()).toList());
+        datahubRecords = getObjectFromJson("ReducedElectricityTaxes.json", DatahubPricelistRecords.class);
+        Map<Instant, BigDecimal> reducedElectricityTaxes = priceListParser
+                .toHourly(Arrays.stream(datahubRecords.records()).toList());
         datahubRecords = getObjectFromJson("TransmissionNetTariffs.json", DatahubPricelistRecords.class);
         Map<Instant, BigDecimal> transmissionNetTariffs = priceListParser
                 .toHourly(Arrays.stream(datahubRecords.records()).toList());
@@ -397,8 +424,10 @@ public class EnergiDataServiceActionsTest {
         when(handler.getTariffs(DatahubTariff.NET_TARIFF)).thenReturn(netTariffs);
         when(handler.getTariffs(DatahubTariff.SYSTEM_TARIFF)).thenReturn(systemTariffs);
         when(handler.getTariffs(DatahubTariff.ELECTRICITY_TAX)).thenReturn(electricityTaxes);
+        when(handler.getTariffs(DatahubTariff.REDUCED_ELECTRICITY_TAX)).thenReturn(reducedElectricityTaxes);
         when(handler.getTariffs(DatahubTariff.TRANSMISSION_NET_TARIFF)).thenReturn(transmissionNetTariffs);
         when(handler.getCurrency()).thenReturn(EnergiDataServiceBindingConstants.CURRENCY_DKK);
+        when(handler.isReducedElectricityTax()).thenReturn(isReducedElectricityTax);
         actions.setThingHandler(handler);
     }
 }
index 5ee45ea673045bd07582f0db29906819d19bea3a..01933cd5588038e0ac15ea3df36c265f0106326f 100644 (file)
@@ -1,18 +1,70 @@
 {
-       "total": 1,
-       "filters": "{\"GLN_Number\":[\"5790000432752\"],\"ChargeType\":[\"D03\"],\"Note\":[\"Elafgift\"]}",
+       "total": 3,
+       "filters": "{\"ChargeType\":[\"D03\"],\"GLN_Number\":[\"5790000432752\"],\"Note\":[\"Elafgift\"]}",
        "dataset": "DatahubPricelist",
        "records": [
                {
-                       "ChargeOwner": "Energinet Systemansvar A/S (SYO)",
-                       "GLN_Number": "5790000432752",
-                       "ChargeType": "D03",
+                       "ValidFrom": "2024-01-01T00:00:00",
+                       "ValidTo": null,
                        "ChargeTypeCode": "EA-001",
-                       "Note": "Elafgift",
-                       "Description": "Elafgiften",
+                       "Price1": 0.761,
+                       "Price2": null,
+                       "Price3": null,
+                       "Price4": null,
+                       "Price5": null,
+                       "Price6": null,
+                       "Price7": null,
+                       "Price8": null,
+                       "Price9": null,
+                       "Price10": null,
+                       "Price11": null,
+                       "Price12": null,
+                       "Price13": null,
+                       "Price14": null,
+                       "Price15": null,
+                       "Price16": null,
+                       "Price17": null,
+                       "Price18": null,
+                       "Price19": null,
+                       "Price20": null,
+                       "Price21": null,
+                       "Price22": null,
+                       "Price23": null,
+                       "Price24": null
+               },
+               {
+                       "ValidFrom": "2023-07-01T00:00:00",
+                       "ValidTo": "2024-01-01T00:00:00",
+                       "ChargeTypeCode": "EA-001",
+                       "Price1": 0.697,
+                       "Price2": null,
+                       "Price3": null,
+                       "Price4": null,
+                       "Price5": null,
+                       "Price6": null,
+                       "Price7": null,
+                       "Price8": null,
+                       "Price9": null,
+                       "Price10": null,
+                       "Price11": null,
+                       "Price12": null,
+                       "Price13": null,
+                       "Price14": null,
+                       "Price15": null,
+                       "Price16": null,
+                       "Price17": null,
+                       "Price18": null,
+                       "Price19": null,
+                       "Price20": null,
+                       "Price21": null,
+                       "Price22": null,
+                       "Price23": null,
+                       "Price24": null
+               },
+               {
                        "ValidFrom": "2023-01-01T00:00:00",
                        "ValidTo": "2023-07-01T00:00:00",
-                       "VATClass": "D02",
+                       "ChargeTypeCode": "EA-001",
                        "Price1": 0.008,
                        "Price2": null,
                        "Price3": null,
                        "Price21": null,
                        "Price22": null,
                        "Price23": null,
-                       "Price24": null,
-                       "TransparentInvoicing": 1,
-                       "TaxIndicator": 1,
-                       "ResolutionDuration": "P1D"
+                       "Price24": null
                }
        ]
 }
index 1af9754e1a6b0f508887b32397d916702559e2d7..c024f6aff81fdd349dc909dad42c876af8fda8ff 100644 (file)
@@ -1,9 +1,153 @@
 {
-       "total": 1,
-       "filters": "{\"ChargeTypeCode\":[\"CD\",\"CD R\"],\"ChargeType\":[\"D03\"],\"GLN_Number\":[\"5790001089030\"]}",
-       "limit": 100,
+       "total": 10,
+       "filters": "{\"ChargeType\":[\"D03\"],\"GLN_Number\":[\"5790001089030\"],\"ChargeTypeCode\":[\"CD R\",\"CD\"]}",
        "dataset": "DatahubPricelist",
        "records": [
+               {
+                       "ValidFrom": "2024-01-01T00:00:00",
+                       "ValidTo": null,
+                       "ChargeTypeCode": "CD",
+                       "Price1": 0.110116,
+                       "Price2": 0.110116,
+                       "Price3": 0.110116,
+                       "Price4": 0.110116,
+                       "Price5": 0.110116,
+                       "Price6": 0.110116,
+                       "Price7": 0.330349,
+                       "Price8": 0.330349,
+                       "Price9": 0.330349,
+                       "Price10": 0.330349,
+                       "Price11": 0.330349,
+                       "Price12": 0.330349,
+                       "Price13": 0.330349,
+                       "Price14": 0.330349,
+                       "Price15": 0.330349,
+                       "Price16": 0.330349,
+                       "Price17": 0.330349,
+                       "Price18": 0.991048,
+                       "Price19": 0.991048,
+                       "Price20": 0.991048,
+                       "Price21": 0.991048,
+                       "Price22": 0.330349,
+                       "Price23": 0.330349,
+                       "Price24": 0.330349
+               },
+               {
+                       "ValidFrom": "2023-10-01T00:00:00",
+                       "ValidTo": "2024-01-01T00:00:00",
+                       "ChargeTypeCode": "CD",
+                       "Price1": 0.2204,
+                       "Price2": 0.2204,
+                       "Price3": 0.2204,
+                       "Price4": 0.2204,
+                       "Price5": 0.2204,
+                       "Price6": 0.2204,
+                       "Price7": 0.2204,
+                       "Price8": 0.2204,
+                       "Price9": 0.2204,
+                       "Price10": 0.2204,
+                       "Price11": 0.2204,
+                       "Price12": 0.2204,
+                       "Price13": 0.2204,
+                       "Price14": 0.2204,
+                       "Price15": 0.2204,
+                       "Price16": 0.2204,
+                       "Price17": 0.2204,
+                       "Price18": 0.617052,
+                       "Price19": 0.617052,
+                       "Price20": 0.617052,
+                       "Price21": 0.2204,
+                       "Price22": 0.2204,
+                       "Price23": 0.2204,
+                       "Price24": 0.2204
+               },
+               {
+                       "ValidFrom": "2023-08-01T00:00:00",
+                       "ValidTo": "2023-10-01T00:00:00",
+                       "ChargeTypeCode": "CD",
+                       "Price1": 0.2204,
+                       "Price2": 0.2204,
+                       "Price3": 0.2204,
+                       "Price4": 0.2204,
+                       "Price5": 0.2204,
+                       "Price6": 0.2204,
+                       "Price7": 0.2204,
+                       "Price8": 0.2204,
+                       "Price9": 0.2204,
+                       "Price10": 0.2204,
+                       "Price11": 0.2204,
+                       "Price12": 0.2204,
+                       "Price13": 0.2204,
+                       "Price14": 0.2204,
+                       "Price15": 0.2204,
+                       "Price16": 0.2204,
+                       "Price17": 0.2204,
+                       "Price18": 0.2204,
+                       "Price19": 0.2204,
+                       "Price20": 0.2204,
+                       "Price21": 0.2204,
+                       "Price22": 0.2204,
+                       "Price23": 0.2204,
+                       "Price24": 0.2204
+               },
+               {
+                       "ValidFrom": "2023-05-01T00:00:00",
+                       "ValidTo": "2023-08-01T00:00:00",
+                       "ChargeTypeCode": "CD",
+                       "Price1": 0.326799,
+                       "Price2": 0.326799,
+                       "Price3": 0.326799,
+                       "Price4": 0.326799,
+                       "Price5": 0.326799,
+                       "Price6": 0.326799,
+                       "Price7": 0.326799,
+                       "Price8": 0.326799,
+                       "Price9": 0.326799,
+                       "Price10": 0.326799,
+                       "Price11": 0.326799,
+                       "Price12": 0.326799,
+                       "Price13": 0.326799,
+                       "Price14": 0.326799,
+                       "Price15": 0.326799,
+                       "Price16": 0.326799,
+                       "Price17": 0.326799,
+                       "Price18": 0.326799,
+                       "Price19": 0.326799,
+                       "Price20": 0.326799,
+                       "Price21": 0.326799,
+                       "Price22": 0.326799,
+                       "Price23": 0.326799,
+                       "Price24": 0.326799
+               },
+               {
+                       "ValidFrom": "2023-04-01T00:00:00",
+                       "ValidTo": "2023-05-01T00:00:00",
+                       "ChargeTypeCode": "CD",
+                       "Price1": 0.432225,
+                       "Price2": 0.432225,
+                       "Price3": 0.432225,
+                       "Price4": 0.432225,
+                       "Price5": 0.432225,
+                       "Price6": 0.432225,
+                       "Price7": 0.432225,
+                       "Price8": 0.432225,
+                       "Price9": 0.432225,
+                       "Price10": 0.432225,
+                       "Price11": 0.432225,
+                       "Price12": 0.432225,
+                       "Price13": 0.432225,
+                       "Price14": 0.432225,
+                       "Price15": 0.432225,
+                       "Price16": 0.432225,
+                       "Price17": 0.432225,
+                       "Price18": 0.432225,
+                       "Price19": 0.432225,
+                       "Price20": 0.432225,
+                       "Price21": 0.432225,
+                       "Price22": 0.432225,
+                       "Price23": 0.432225,
+                       "Price24": 0.432225
+               },
                {
                        "ValidFrom": "2023-01-01T00:00:00",
                        "ValidTo": "2023-04-01T00:00:00",
                        "Price22": 0.432225,
                        "Price23": 0.432225,
                        "Price24": 0.432225
+               },
+               {
+                       "ValidFrom": "2024-01-01T00:00:00",
+                       "ValidTo": null,
+                       "ChargeTypeCode": "CD R",
+                       "Price1": 0.0,
+                       "Price2": 0.0,
+                       "Price3": 0.0,
+                       "Price4": 0.0,
+                       "Price5": 0.0,
+                       "Price6": 0.0,
+                       "Price7": 0.0,
+                       "Price8": 0.0,
+                       "Price9": 0.0,
+                       "Price10": 0.0,
+                       "Price11": 0.0,
+                       "Price12": 0.0,
+                       "Price13": 0.0,
+                       "Price14": 0.0,
+                       "Price15": 0.0,
+                       "Price16": 0.0,
+                       "Price17": 0.0,
+                       "Price18": 0.0,
+                       "Price19": 0.0,
+                       "Price20": 0.0,
+                       "Price21": 0.0,
+                       "Price22": 0.0,
+                       "Price23": 0.0,
+                       "Price24": 0.0
+               },
+               {
+                       "ValidFrom": "2023-10-01T00:00:00",
+                       "ValidTo": "2024-01-01T00:00:00",
+                       "ChargeTypeCode": "CD R",
+                       "Price1": -0.2204,
+                       "Price2": -0.2204,
+                       "Price3": -0.2204,
+                       "Price4": -0.2204,
+                       "Price5": -0.2204,
+                       "Price6": -0.2204,
+                       "Price7": -0.2204,
+                       "Price8": -0.2204,
+                       "Price9": -0.2204,
+                       "Price10": -0.2204,
+                       "Price11": -0.2204,
+                       "Price12": -0.2204,
+                       "Price13": -0.2204,
+                       "Price14": -0.2204,
+                       "Price15": -0.2204,
+                       "Price16": -0.2204,
+                       "Price17": -0.2204,
+                       "Price18": -0.617052,
+                       "Price19": -0.617052,
+                       "Price20": -0.617052,
+                       "Price21": -0.2204,
+                       "Price22": -0.2204,
+                       "Price23": -0.2204,
+                       "Price24": -0.2204
+               },
+               {
+                       "ValidFrom": "2023-08-01T00:00:00",
+                       "ValidTo": "2023-10-01T00:00:00",
+                       "ChargeTypeCode": "CD R",
+                       "Price1": -0.2204,
+                       "Price2": -0.2204,
+                       "Price3": -0.2204,
+                       "Price4": -0.2204,
+                       "Price5": -0.2204,
+                       "Price6": -0.2204,
+                       "Price7": -0.2204,
+                       "Price8": -0.2204,
+                       "Price9": -0.2204,
+                       "Price10": -0.2204,
+                       "Price11": -0.2204,
+                       "Price12": -0.2204,
+                       "Price13": -0.2204,
+                       "Price14": -0.2204,
+                       "Price15": -0.2204,
+                       "Price16": -0.2204,
+                       "Price17": -0.2204,
+                       "Price18": -0.2204,
+                       "Price19": -0.2204,
+                       "Price20": -0.2204,
+                       "Price21": -0.2204,
+                       "Price22": -0.2204,
+                       "Price23": -0.2204,
+                       "Price24": -0.2204
+               },
+               {
+                       "ValidFrom": "2023-01-01T00:00:00",
+                       "ValidTo": "2023-08-01T00:00:00",
+                       "ChargeTypeCode": "CD R",
+                       "Price1": 0.0,
+                       "Price2": 0.0,
+                       "Price3": 0.0,
+                       "Price4": 0.0,
+                       "Price5": 0.0,
+                       "Price6": 0.0,
+                       "Price7": 0.0,
+                       "Price8": 0.0,
+                       "Price9": 0.0,
+                       "Price10": 0.0,
+                       "Price11": 0.0,
+                       "Price12": 0.0,
+                       "Price13": 0.0,
+                       "Price14": 0.0,
+                       "Price15": 0.0,
+                       "Price16": 0.0,
+                       "Price17": 0.0,
+                       "Price18": 0.0,
+                       "Price19": 0.0,
+                       "Price20": 0.0,
+                       "Price21": 0.0,
+                       "Price22": 0.0,
+                       "Price23": 0.0,
+                       "Price24": 0.0
                }
        ]
 }
diff --git a/bundles/org.openhab.binding.energidataservice/src/test/resources/org/openhab/binding/energidataservice/internal/action/ReducedElectricityTaxes.json b/bundles/org.openhab.binding.energidataservice/src/test/resources/org/openhab/binding/energidataservice/internal/action/ReducedElectricityTaxes.json
new file mode 100644 (file)
index 0000000..a482793
--- /dev/null
@@ -0,0 +1,46 @@
+{
+       "total": 1,
+       "filters": "{\"ChargeType\":[\"D03\"],\"GLN_Number\":[\"5790000432752\"],\"Note\":[\"Reduceret elafgift\"]}",
+       "sort": "ValidFrom DESC",
+       "dataset": "DatahubPricelist",
+       "records": [
+               {
+                       "ChargeOwner": "Energinet Systemansvar A/S (SYO)",
+                       "GLN_Number": "5790000432752",
+                       "ChargeType": "D03",
+                       "ChargeTypeCode": "EA-002",
+                       "Note": "Reduceret elafgift",
+                       "Description": "Reduceret elafgift for elvarmekunder",
+                       "ValidFrom": "2021-02-01T00:00:00",
+                       "ValidTo": null,
+                       "VATClass": "D02",
+                       "Price1": 0.008,
+                       "Price2": null,
+                       "Price3": null,
+                       "Price4": null,
+                       "Price5": null,
+                       "Price6": null,
+                       "Price7": null,
+                       "Price8": null,
+                       "Price9": null,
+                       "Price10": null,
+                       "Price11": null,
+                       "Price12": null,
+                       "Price13": null,
+                       "Price14": null,
+                       "Price15": null,
+                       "Price16": null,
+                       "Price17": null,
+                       "Price18": null,
+                       "Price19": null,
+                       "Price20": null,
+                       "Price21": null,
+                       "Price22": null,
+                       "Price23": null,
+                       "Price24": null,
+                       "TransparentInvoicing": 1,
+                       "TaxIndicator": 1,
+                       "ResolutionDuration": "P1D"
+               }
+       ]
+}
diff --git a/bundles/org.openhab.binding.energidataservice/src/test/resources/org/openhab/binding/energidataservice/internal/action/SpotPrices20231003.json b/bundles/org.openhab.binding.energidataservice/src/test/resources/org/openhab/binding/energidataservice/internal/action/SpotPrices20231003.json
new file mode 100644 (file)
index 0000000..497c2b8
--- /dev/null
@@ -0,0 +1,18 @@
+[
+       {
+               "hourStart": "2023-10-03T20:00:00Z",
+               "spotPrice": 0.020059999
+       },
+       {
+               "hourStart": "2023-10-03T21:00:00Z",
+               "spotPrice": 0.00544
+       },
+       {
+               "hourStart": "2023-10-03T22:00:00Z",
+               "spotPrice": 0.00097
+       },
+       {
+               "hourStart": "2023-10-03T23:00:00Z",
+               "spotPrice": 0.00007
+       }
+]