Rename price element to price component (#15935)

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
Jacob Laursen 2023-11-20 23:18:46 +01:00 committed by GitHub
parent ff873fff14
commit b2b7602eee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 37 deletions

View File

@ -40,7 +40,7 @@ To obtain the Global Location Number of your grid company:
For customers using electricity for heating, a reduced electricity tax rate may apply after consuming the first 4000 kWh within a year. 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. 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. This will ensure that thing action calculations use the reduced electricity tax rate when price components are not explicitly provided.
It will not impact channels, see [Electricity Tax](#electricity-tax) for further information. It will not impact channels, see [Electricity Tax](#electricity-tax) for further information.
## Channels ## Channels
@ -170,7 +170,7 @@ 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 deserializing JSON from the [hourly-prices](#hourly-prices) channel.
This is more convenient, much faster, and provides automatic summation of the price elements of interest. This is more convenient, much faster, 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.
@ -327,14 +327,14 @@ var price = actions.calculatePrice(now.toInstant(), now.plusHours(4).toInstant,
| Parameter | Type | Description | | Parameter | Type | Description |
|--------------------|-----------------------------|--------------------------------------------------------| |--------------------|-----------------------------|--------------------------------------------------------|
| priceElements | `String` | Comma-separated list of price elements to include | | priceComponents | `String` | Comma-separated list of price components to include |
**Result:** `Map<Instant, BigDecimal>` **Result:** `Map<Instant, BigDecimal>`
The parameter `priceElements` is a case-insensitive comma-separated list of price elements to include in the returned hourly prices. The parameter `priceComponents` is a case-insensitive comma-separated list of price components to include in the returned hourly prices.
These elements can be requested: These components can be requested:
| Price element | Description | | Price component | Description |
|-----------------------|-------------------------| |-----------------------|-------------------------|
| SpotPrice | Spot price | | SpotPrice | Spot price |
| NetTariff | Net tariff | | NetTariff | Net tariff |
@ -343,7 +343,7 @@ These elements can be requested:
| ReducedElectricityTax | Reduced electricity tax | | ReducedElectricityTax | Reduced electricity tax |
| TransmissionNetTariff | Transmission net tariff | | TransmissionNetTariff | Transmission net tariff |
Using `null` as parameter returns the total prices including all price elements. Using `null` as parameter returns the total prices including all price components.
If **Reduced Electricity Tax** is set in Thing configuration, `ElectricityTax` will be excluded, otherwise `ReducedElectricityTax`. 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. This logic ensures consistent and comparable results not affected by artifical changes in the rate for electricity tax two times per year.

View File

@ -61,7 +61,7 @@ public class EnergiDataServiceActions implements ThingActions {
private @Nullable EnergiDataServiceHandler handler; private @Nullable EnergiDataServiceHandler handler;
private enum PriceElement { private enum PriceComponent {
SPOT_PRICE("spotprice", null), SPOT_PRICE("spotprice", null),
NET_TARIFF("nettariff", DatahubTariff.NET_TARIFF), NET_TARIFF("nettariff", DatahubTariff.NET_TARIFF),
SYSTEM_TARIFF("systemtariff", DatahubTariff.SYSTEM_TARIFF), SYSTEM_TARIFF("systemtariff", DatahubTariff.SYSTEM_TARIFF),
@ -69,13 +69,13 @@ public class EnergiDataServiceActions implements ThingActions {
REDUCED_ELECTRICITY_TAX("reducedelectricitytax", DatahubTariff.REDUCED_ELECTRICITY_TAX), REDUCED_ELECTRICITY_TAX("reducedelectricitytax", DatahubTariff.REDUCED_ELECTRICITY_TAX),
TRANSMISSION_NET_TARIFF("transmissionnettariff", DatahubTariff.TRANSMISSION_NET_TARIFF); TRANSMISSION_NET_TARIFF("transmissionnettariff", DatahubTariff.TRANSMISSION_NET_TARIFF);
private static final Map<String, PriceElement> NAME_MAP = Stream.of(values()) private static final Map<String, PriceComponent> NAME_MAP = Stream.of(values())
.collect(Collectors.toMap(PriceElement::toString, Function.identity())); .collect(Collectors.toMap(PriceComponent::toString, Function.identity()));
private String name; private String name;
private @Nullable DatahubTariff datahubTariff; private @Nullable DatahubTariff datahubTariff;
private PriceElement(String name, @Nullable DatahubTariff datahubTariff) { private PriceComponent(String name, @Nullable DatahubTariff datahubTariff) {
this.name = name; this.name = name;
this.datahubTariff = datahubTariff; this.datahubTariff = datahubTariff;
} }
@ -85,8 +85,8 @@ public class EnergiDataServiceActions implements ThingActions {
return name; return name;
} }
public static PriceElement fromString(final String name) { public static PriceComponent fromString(final String name) {
PriceElement myEnum = NAME_MAP.get(name.toLowerCase()); PriceComponent myEnum = NAME_MAP.get(name.toLowerCase());
if (null == myEnum) { if (null == myEnum) {
throw new IllegalArgumentException(String.format("'%s' has no corresponding value. Accepted values: %s", throw new IllegalArgumentException(String.format("'%s' has no corresponding value. Accepted values: %s",
name, Arrays.asList(values()))); name, Arrays.asList(values())));
@ -109,30 +109,30 @@ public class EnergiDataServiceActions implements ThingActions {
boolean isReducedElectricityTax = handler.isReducedElectricityTax(); boolean isReducedElectricityTax = handler.isReducedElectricityTax();
return getPrices(Arrays.stream(PriceElement.values()) return getPrices(Arrays.stream(PriceComponent.values())
.filter(element -> element != (isReducedElectricityTax ? PriceElement.ELECTRICITY_TAX .filter(component -> component != (isReducedElectricityTax ? PriceComponent.ELECTRICITY_TAX
: PriceElement.REDUCED_ELECTRICITY_TAX)) : PriceComponent.REDUCED_ELECTRICITY_TAX))
.collect(Collectors.toSet())); .collect(Collectors.toSet()));
} }
@RuleAction(label = "@text/action.get-prices.label", description = "@text/action.get-prices.description") @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( public @ActionOutput(name = "prices", type = "java.util.Map<java.time.Instant, java.math.BigDecimal>") Map<Instant, BigDecimal> getPrices(
@ActionInput(name = "priceElements", label = "@text/action.get-prices.priceElements.label", description = "@text/action.get-prices.priceElements.description") @Nullable String priceElements) { @ActionInput(name = "priceComponents", label = "@text/action.get-prices.priceComponents.label", description = "@text/action.get-prices.priceComponents.description") @Nullable String priceComponents) {
if (priceElements == null) { if (priceComponents == null) {
logger.warn("Argument 'priceElements' is null"); logger.warn("Argument 'priceComponents' is null");
return Map.of(); return Map.of();
} }
Set<PriceElement> priceElementsSet; Set<PriceComponent> priceComponentsSet;
try { try {
priceElementsSet = new HashSet<PriceElement>( priceComponentsSet = new HashSet<PriceComponent>(
Arrays.stream(priceElements.split(",")).map(PriceElement::fromString).toList()); Arrays.stream(priceComponents.split(",")).map(PriceComponent::fromString).toList());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
logger.warn("{}", e.getMessage()); logger.warn("{}", e.getMessage());
return Map.of(); return Map.of();
} }
return getPrices(priceElementsSet); return getPrices(priceComponentsSet);
} }
@RuleAction(label = "@text/action.calculate-price.label", description = "@text/action.calculate-price.description") @RuleAction(label = "@text/action.calculate-price.label", description = "@text/action.calculate-price.description")
@ -233,7 +233,7 @@ public class EnergiDataServiceActions implements ThingActions {
} }
} }
private Map<Instant, BigDecimal> getPrices(Set<PriceElement> priceElements) { private Map<Instant, BigDecimal> getPrices(Set<PriceComponent> priceComponents) {
EnergiDataServiceHandler handler = this.handler; EnergiDataServiceHandler handler = this.handler;
if (handler == null) { if (handler == null) {
logger.warn("EnergiDataServiceActions ThingHandler is null."); logger.warn("EnergiDataServiceActions ThingHandler is null.");
@ -242,8 +242,8 @@ public class EnergiDataServiceActions implements ThingActions {
Map<Instant, BigDecimal> prices; Map<Instant, BigDecimal> prices;
boolean spotPricesRequired; boolean spotPricesRequired;
if (priceElements.contains(PriceElement.SPOT_PRICE)) { if (priceComponents.contains(PriceComponent.SPOT_PRICE)) {
if (priceElements.size() > 1 && !handler.getCurrency().equals(CURRENCY_DKK)) { if (priceComponents.size() > 1 && !handler.getCurrency().equals(CURRENCY_DKK)) {
logger.warn("Cannot calculate sum when spot price currency is {}", handler.getCurrency()); logger.warn("Cannot calculate sum when spot price currency is {}", handler.getCurrency());
return Map.of(); return Map.of();
} }
@ -254,13 +254,13 @@ public class EnergiDataServiceActions implements ThingActions {
prices = new HashMap<>(); prices = new HashMap<>();
} }
for (PriceElement priceElement : PriceElement.values()) { for (PriceComponent priceComponent : PriceComponent.values()) {
DatahubTariff datahubTariff = priceElement.getDatahubTariff(); DatahubTariff datahubTariff = priceComponent.getDatahubTariff();
if (datahubTariff == null) { if (datahubTariff == null) {
continue; continue;
} }
if (priceElements.contains(priceElement)) { if (priceComponents.contains(priceComponent)) {
Map<Instant, BigDecimal> tariffMap = handler.getTariffs(datahubTariff); Map<Instant, BigDecimal> tariffMap = handler.getTariffs(datahubTariff);
mergeMaps(prices, tariffMap, !spotPricesRequired); mergeMaps(prices, tariffMap, !spotPricesRequired);
} }
@ -287,13 +287,13 @@ public class EnergiDataServiceActions implements ThingActions {
* Static get prices method for DSL rule compatibility. * Static get prices method for DSL rule compatibility.
* *
* @param actions * @param actions
* @param priceElements Comma-separated list of price elements to include in prices. * @param priceComponents Comma-separated list of price components to include in prices.
* @return Map of prices * @return Map of prices
*/ */
public static Map<Instant, BigDecimal> getPrices(@Nullable ThingActions actions, @Nullable String priceElements) { public static Map<Instant, BigDecimal> getPrices(@Nullable ThingActions actions, @Nullable String priceComponents) {
if (actions instanceof EnergiDataServiceActions serviceActions) { if (actions instanceof EnergiDataServiceActions serviceActions) {
if (priceElements != null && !priceElements.isBlank()) { if (priceComponents != null && !priceComponents.isBlank()) {
return serviceActions.getPrices(priceElements); return serviceActions.getPrices(priceComponents);
} else { } else {
return serviceActions.getPrices(); return serviceActions.getPrices();
} }

View File

@ -108,5 +108,5 @@ action.calculate-price.label = calculate price
action.calculate-price.description = calculate price for power consumption in period excl. VAT action.calculate-price.description = calculate price for power consumption in period excl. VAT
action.get-prices.label = get prices action.get-prices.label = get prices
action.get-prices.description = get hourly prices excl. VAT action.get-prices.description = get hourly prices excl. VAT
action.get-prices.priceElements.label = price elements action.get-prices.priceComponents.label = price components
action.get-prices.priceElements.description = comma-separated list of price elements to include in sums action.get-prices.priceComponents.description = comma-separated list of price components to include in sums

View File

@ -198,7 +198,7 @@ public class EnergiDataServiceActionsTest {
} }
@Test @Test
void getPricesTotalAllElements() throws IOException { void getPricesTotalAllComponents() throws IOException {
mockCommonDatasets(actions); mockCommonDatasets(actions);
Map<Instant, BigDecimal> actual = actions Map<Instant, BigDecimal> actual = actions
@ -210,7 +210,7 @@ public class EnergiDataServiceActionsTest {
} }
@Test @Test
void getPricesInvalidPriceElement() throws IOException { void getPricesInvalidPriceComponent() throws IOException {
mockCommonDatasets(actions); mockCommonDatasets(actions);
Map<Instant, BigDecimal> actual = actions.getPrices("spotprice,nettarif"); Map<Instant, BigDecimal> actual = actions.getPrices("spotprice,nettarif");