Improve error handling for action calculatePrice (#16651)

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
Jacob Laursen 2024-04-14 09:23:41 +02:00 committed by Ciprian Pascu
parent 366dd052b1
commit 29e5392598
3 changed files with 18 additions and 8 deletions

View File

@ -303,6 +303,7 @@ var Map<String, Object> result = actions.calculateCheapestPeriod(now.toInstant()
**Result:** Price as `BigDecimal`.
This action calculates the price for using given amount of power in the period from `start` till `end`.
Returns `null` if the calculation cannot be performed due to missing price data within the requested period.
Example:
@ -402,7 +403,9 @@ var priceMap = actions.getPrices("SpotPrice,GridTariff");
logInfo("Current spot price + grid tariff excl. VAT", priceMap.get(hourStart).toString)
var price = actions.calculatePrice(Instant.now, now.plusHours(1).toInstant, 150 | W)
logInfo("Total price for using 150 W for the next hour", price.toString)
if (price != null) {
logInfo("Total price for using 150 W for the next hour", price.toString)
}
val ArrayList<Duration> durationPhases = new ArrayList<Duration>()
durationPhases.add(Duration.ofMinutes(37))
@ -467,7 +470,9 @@ utils.javaMapToJsMap(edsActions.getPrices("SpotPrice,GridTariff")).forEach((valu
console.log("Current spot price + grid tariff excl. VAT: " + priceMap.get(hourStart.toString()));
var price = edsActions.calculatePrice(time.Instant.now(), time.Instant.now().plusSeconds(3600), Quantity("150 W"));
console.log("Total price for using 150 W for the next hour: " + price.toString());
if (price !== null) {
console.log("Total price for using 150 W for the next hour: " + price.toString());
}
var durationPhases = [];
durationPhases.push(time.Duration.ofMinutes(37));

View File

@ -139,7 +139,7 @@ public class EnergiDataServiceActions implements ThingActions {
}
@RuleAction(label = "@text/action.calculate-price.label", description = "@text/action.calculate-price.description")
public @ActionOutput(name = "price", type = "java.math.BigDecimal") BigDecimal calculatePrice(
public @ActionOutput(name = "price", type = "java.math.BigDecimal") @Nullable BigDecimal calculatePrice(
@ActionInput(name = "start", type = "java.time.Instant") Instant start,
@ActionInput(name = "end", type = "java.time.Instant") Instant end,
@ActionInput(name = "power", type = "QuantityType<Power>") QuantityType<Power> power) {
@ -149,7 +149,7 @@ public class EnergiDataServiceActions implements ThingActions {
return priceCalculator.calculatePrice(start, end, power);
} catch (MissingPriceException e) {
logger.warn("{}", e.getMessage());
return BigDecimal.ZERO;
return null;
}
}
@ -314,10 +314,10 @@ public class EnergiDataServiceActions implements ThingActions {
* @param power Constant power consumption
* @return Map of prices
*/
public static BigDecimal calculatePrice(@Nullable ThingActions actions, @Nullable Instant start,
public static @Nullable BigDecimal calculatePrice(@Nullable ThingActions actions, @Nullable Instant start,
@Nullable Instant end, @Nullable QuantityType<Power> power) {
if (start == null || end == null || power == null) {
return BigDecimal.ZERO;
return null;
}
if (actions instanceof EnergiDataServiceActions serviceActions) {
return serviceActions.calculatePrice(start, end, power);

View File

@ -33,6 +33,7 @@ import java.util.stream.Collectors;
import javax.measure.quantity.Power;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -239,6 +240,7 @@ public class EnergiDataServiceActionsTest {
void calculatePriceSimple() throws IOException {
mockCommonDatasets(actions);
@Nullable
BigDecimal actual = actions.calculatePrice(Instant.parse("2023-02-04T15:30:00Z"),
Instant.parse("2023-02-04T16:30:00Z"), new QuantityType<>(150, Units.WATT));
assertThat(actual, is(equalTo(new BigDecimal("0.311447631975000000")))); // 0.3114476319750
@ -257,6 +259,7 @@ public class EnergiDataServiceActionsTest {
void calculatePriceFullHours() throws IOException {
mockCommonDatasets(actions);
@Nullable
BigDecimal actual = actions.calculatePrice(Instant.parse("2023-02-04T15:00:00Z"),
Instant.parse("2023-02-04T17:00:00Z"), new QuantityType<>(1, Units.KILOVAR));
assertThat(actual, is(equalTo(new BigDecimal("4.152635093000000000")))); // 4.152635093
@ -266,18 +269,20 @@ public class EnergiDataServiceActionsTest {
void calculatePriceOutOfRangeStart() throws IOException {
mockCommonDatasets(actions);
@Nullable
BigDecimal actual = actions.calculatePrice(Instant.parse("2023-02-03T23:59:00Z"),
Instant.parse("2023-02-04T12:30:00Z"), new QuantityType<>(1000, Units.WATT));
assertThat(actual, is(equalTo(BigDecimal.ZERO)));
assertThat(actual, is(nullValue()));
}
@Test
void calculatePriceOutOfRangeEnd() throws IOException {
mockCommonDatasets(actions);
@Nullable
BigDecimal actual = actions.calculatePrice(Instant.parse("2023-02-05T22:00:00Z"),
Instant.parse("2023-02-05T23:01:00Z"), new QuantityType<>(1000, Units.WATT));
assertThat(actual, is(equalTo(BigDecimal.ZERO)));
assertThat(actual, is(nullValue()));
}
/**