diff --git a/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/extensions/PersistenceExtensions.java b/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/extensions/PersistenceExtensions.java
index e132e2a8382..8c1031f5a2b 100644
--- a/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/extensions/PersistenceExtensions.java
+++ b/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/extensions/PersistenceExtensions.java
@@ -71,6 +71,7 @@
* @author Mark Herwege - add median methods
* @author Mark Herwege - use item lastChange and lastUpdate methods if not in peristence
* @author Mark Herwege - add Riemann sum methods
+ * @author Mark Herwege - use base unit for calculations and results
*/
@Component(immediate = true)
@NonNullByDefault
@@ -1158,6 +1159,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param timestamp the point in time from which to compute the variance
* @return the variance between then and now, or null
if timestamp
is in the future, if
@@ -1172,6 +1177,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the variance of the state of the given {@link Item} since a certain point in time.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param timestamp the point in time from which to compute the variance
* @param type LEFT, RIGHT, MIDPOINT or TRAPEZOIDAL representing approximation types for Riemann sums
@@ -1188,6 +1197,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param timestamp the point in time to which to compute the variance
* @return the variance between now and then, or null
if timestamp
is in the past, if
@@ -1202,6 +1215,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the variance of the state of the given {@link Item} until a certain point in time.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param timestamp the point in time to which to compute the variance
* @param type LEFT, RIGHT, MIDPOINT or TRAPEZOIDAL representing approximation types for Riemann sums
@@ -1218,6 +1235,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param begin the point in time from which to compute
* @param end the end time for the computation
@@ -1237,6 +1258,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the variance of the state of the given {@link Item} between two certain point in time.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param begin the point in time from which to compute the variance
* @param end the end time for the computation
@@ -1256,6 +1281,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param timestamp the point in time from which to compute the variance
* @param serviceId the name of the {@link PersistenceService} to use
@@ -1272,6 +1301,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the variance of the state of the given {@link Item} since a certain point in time.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param timestamp the point in time from which to compute the variance
* @param type LEFT, RIGHT, MIDPOINT or TRAPEZOIDAL representing approximation types for Riemann sums
@@ -1291,6 +1324,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param timestamp the point in time to which to compute the variance
* @param serviceId the name of the {@link PersistenceService} to use
@@ -1307,6 +1344,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the variance of the state of the given {@link Item} until a certain point in time.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param timestamp the point in time to which to compute the variance
* @param type LEFT, RIGHT, MIDPOINT or TRAPEZOIDAL representing approximation types for Riemann sums
@@ -1326,6 +1367,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param begin the point in time from which to compute the variance
* @param end the end time for the computation
@@ -1342,6 +1387,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the variance of the state of the given {@link Item} between two points in time.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the variance for
* @param begin the point in time from which to compute
* @param end the end time for the computation
@@ -1381,8 +1430,7 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
it = result.iterator();
}
Item baseItem = item instanceof GroupItem groupItem ? groupItem.getBaseItem() : item;
- Unit> unit = (baseItem instanceof NumberItem numberItem)
- && (numberItem.getUnit() instanceof Unit> numberItemUnit) ? numberItemUnit.getSystemUnit() : null;
+ Unit> unit = (baseItem instanceof NumberItem numberItem) ? numberItem.getUnit() : null;
BigDecimal average = average(beginTime, endTime, it, unit, type);
if (average != null) {
@@ -1417,6 +1465,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1435,6 +1487,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the standard deviation of the state of the given {@link Item} since a certain point in time.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1455,6 +1511,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1473,6 +1533,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the standard deviation of the state of the given {@link Item} until a certain point in time.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1493,6 +1557,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1512,6 +1580,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the standard deviation of the state of the given {@link Item} between two points in time.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1534,6 +1606,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1553,6 +1629,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the standard deviation of the state of the given {@link Item} since a certain point in time.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1575,6 +1655,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1594,6 +1678,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the standard deviation of the state of the given {@link Item} until a certain point in time.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1616,6 +1704,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* A left approximation type is used for the Riemann sum.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1638,6 +1730,10 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the standard deviation of the state of the given {@link Item} between two points in time.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* Note: If you need variance and standard deviation at the same time do not query both as it is a costly
* operation. Get the variance only, it is the squared deviation.
*
@@ -1664,21 +1760,23 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
return null;
}
State variance = internalVarianceBetween(item, begin, end, type, effectiveServiceId);
+ if (variance == null) {
+ return null;
+ }
- if (variance != null) {
- DecimalType dt = variance.as(DecimalType.class);
- // avoid ArithmeticException if variance is less than zero
- if (dt != null && DecimalType.ZERO.compareTo(dt) <= 0) {
- BigDecimal deviation = dt.toBigDecimal().sqrt(MathContext.DECIMAL64);
- Item baseItem = item instanceof GroupItem groupItem ? groupItem.getBaseItem() : item;
- Unit> unit = (baseItem instanceof NumberItem numberItem)
- && (numberItem.getUnit() instanceof Unit> numberItemUnit) ? numberItemUnit.getSystemUnit()
- : null;
- if (unit != null) {
- return new QuantityType<>(deviation, unit);
- } else {
- return new DecimalType(deviation);
- }
+ Unit> varianceUnit = (variance instanceof QuantityType> quantity) ? quantity.getUnit() : null;
+ DecimalType dt = variance.as(DecimalType.class);
+
+ // avoid ArithmeticException if variance is less than zero
+ if (dt != null && DecimalType.ZERO.compareTo(dt) <= 0) {
+ BigDecimal deviation = dt.toBigDecimal().sqrt(MathContext.DECIMAL64);
+
+ Item baseItem = item instanceof GroupItem groupItem ? groupItem.getBaseItem() : item;
+ Unit> unit = baseItem instanceof NumberItem numberItem ? numberItem.getUnit() : null;
+ if (varianceUnit != null && unit != null) {
+ return (new QuantityType<>(deviation, varianceUnit.root(2))).toUnit(unit);
+ } else {
+ return new DecimalType(deviation);
}
}
return null;
@@ -1938,10 +2036,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the Riemann sum of the states of a given {@link Item} since a certain point in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
* A left approximation type is used for the Riemann sum.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param timestamp the point in time from which to search for the riemannSum value
* @return the Riemann sum since timestamp
or null
if no
@@ -1955,10 +2059,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
/**
* Gets the Riemann sum of the states of a given {@link Item} since a certain point in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param timestamp the point in time from which to search for the riemannSum value
* @param type LEFT, RIGHT, MIDPOINT or TRAPEZOIDAL representing approximation types for Riemann sums
@@ -1974,10 +2084,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the Riemann sum of the states of a given {@link Item} until a certain point in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
* A left approximation type is used for the Riemann sum.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param timestamp the point in time to which to search for the riemannSum value
* @return the Riemann sum until timestamp
or null
if no
@@ -1991,10 +2107,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
/**
* Gets the Riemann sum of the states of a given {@link Item} until a certain point in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param timestamp the point in time to which to search for the riemannSum value
* @param type LEFT, RIGHT, MIDPOINT or TRAPEZOIDAL representing approximation types for Riemann sums
@@ -2010,10 +2132,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the Riemann sum of the states of a given {@link Item} between two certain points in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
* A left approximation type is used for the Riemann sum.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param begin the point in time from which to start the summation
* @param end the point in time to which to start the summation
@@ -2028,10 +2156,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
/**
* Gets the Riemann sum of the states of a given {@link Item} between two certain points in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param begin the point in time from which to start the summation
* @param end the point in time to which to start the summation
@@ -2049,10 +2183,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the Riemann sum of the states of a given {@link Item} since a certain point in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
* A left approximation type is used for the Riemann sum.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param timestamp the point in time from which to search for the riemannSum value
* @param serviceId the name of the {@link PersistenceService} to use
@@ -2068,10 +2208,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
/**
* Gets the Riemann sum of the states of a given {@link Item} since a certain point in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param timestamp the point in time from which to search for the riemannSum value
* @param type LEFT, RIGHT, MIDPOINT or TRAPEZOIDAL representing approximation types for Riemann sums
@@ -2090,10 +2236,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the Riemann sum of the states of a given {@link Item} until a certain point in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
* A left approximation type is used for the Riemann sum.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param timestamp the point in time to which to search for the riemannSum value
* @param serviceId the name of the {@link PersistenceService} to use
@@ -2109,10 +2261,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
/**
* Gets the Riemann sum of the states of a given {@link Item} until a certain point in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param timestamp the point in time to which to search for the riemannSum value
* @param type LEFT, RIGHT, MIDPOINT or TRAPEZOIDAL representing approximation types for Riemann sums
@@ -2131,10 +2289,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
* Gets the Riemann sum of the states of a given {@link Item} between two certain points in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
* A left approximation type is used for the Riemann sum.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param begin the point in time from which to start the summation
* @param end the point in time to which to start the summation
@@ -2151,10 +2315,16 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
/**
* Gets the Riemann sum of the states of a given {@link Item} between two certain points in time.
* This can be used as an approximation for integrating the curve represented by discrete values.
- * The time dimension in the result is in seconds, therefore if you do not use QuantityType results, you may have to
+ *
+ * Note: The time dimension in the result is in seconds, therefore if you do not use QuantityType results,
+ * you may have to
* multiply or divide to get the result in the expected scale.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the riemannSum value for
* @param begin the point in time from which to start the summation
* @param end the point in time to which to start the summation
@@ -2193,8 +2363,7 @@ private static void internalPersist(Item item, TimeSeries timeSeries, @Nullable
}
Item baseItem = item instanceof GroupItem groupItem ? groupItem.getBaseItem() : item;
- Unit> unit = (baseItem instanceof NumberItem numberItem)
- && (numberItem.getUnit() instanceof Unit> numberItemUnit) ? numberItemUnit.getSystemUnit() : null;
+ Unit> unit = (baseItem instanceof NumberItem numberItem) ? numberItem.getUnit() : null;
BigDecimal sum = riemannSum(beginTime, endTime, it, unit, type).scaleByPowerOfTen(-3);
if (unit != null) {
return new QuantityType<>(sum, unit.multiply(Units.SECOND));
@@ -2443,6 +2612,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* value.
* The default persistence service is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the item for which we will sum its persisted state values since timestamp
* @param timestamp the point in time from which to start the summation
* @return the sum of the state values since timestamp
, or null if timestamp
is in the
@@ -2458,6 +2631,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* value.
* The default persistence service is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the item for which we will sum its persisted state values to timestamp
* @param timestamp the point in time to which to start the summation
* @return the sum of the state values until timestamp
, or null if timestamp
is in the
@@ -2473,6 +2650,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* value.
* The default persistence service is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the item for which we will sum its persisted state values between begin
and
* end
* @param begin the point in time from which to start the summation
@@ -2491,6 +2672,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* value.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the item for which we will sum its persisted state values since timestamp
* @param timestamp the point in time from which to start the summation
* @param serviceId the name of the {@link PersistenceService} to use
@@ -2507,6 +2692,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* value.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the item for which we will sum its persisted state values to timestamp
* @param timestamp the point in time to which to start the summation
* @param serviceId the name of the {@link PersistenceService} to use
@@ -2523,6 +2712,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* value.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the item for which we will sum its persisted state values between begin
and
* end
* @param begin the point in time from which to start the summation
@@ -2547,8 +2740,7 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
Iterator it = result.iterator();
Item baseItem = item instanceof GroupItem groupItem ? groupItem.getBaseItem() : item;
- Unit> unit = (baseItem instanceof NumberItem numberItem)
- && (numberItem.getUnit() instanceof Unit> numberItemUnit) ? numberItemUnit.getSystemUnit() : null;
+ Unit> unit = baseItem instanceof NumberItem numberItem ? numberItem.getUnit() : null;
BigDecimal sum = BigDecimal.ZERO;
while (it.hasNext()) {
HistoricItem historicItem = it.next();
@@ -2681,10 +2873,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
}
if (begin == null && end != null && end.isAfter(ZonedDateTime.now())) {
- valueStart = getItemValue(item);
+ valueStart = getItemValue(item, unit);
}
if (begin != null && end == null && begin.isBefore(ZonedDateTime.now())) {
- valueStop = getItemValue(item);
+ valueStop = getItemValue(item, unit);
}
if (valueStart != null && valueStop != null) {
@@ -2700,6 +2892,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
*
* This method has been deprecated and {@link #evolutionRateSince(Item, ZonedDateTime)} should be used instead.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the item to get the evolution rate value for
* @param timestamp the point in time from which to compute the evolution rate
* @return the evolution rate in percent (positive and negative) between now and then, or null
if
@@ -2719,6 +2915,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* Gets the evolution rate of the state of a given {@link Item} since a certain point in time.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the item to get the evolution rate value for
* @param timestamp the point in time from which to compute the evolution rate
* @return the evolution rate in percent (positive and negative) between now and then, or null
if
@@ -2735,6 +2935,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* Gets the evolution rate of the state of a given {@link Item} until a certain point in time.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the item to get the evolution rate value for
* @param timestamp the point in time to which to compute the evolution rate
* @return the evolution rate in percent (positive and negative) between then and now, or null
if
@@ -2754,6 +2958,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* This method has been deprecated and {@link #evolutionRateBetween(Item, ZonedDateTime, ZonedDateTime)} should be
* used instead.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the item to get the evolution rate value for
* @param begin the beginning point in time
* @param end the end point in time
@@ -2774,6 +2982,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* Gets the evolution rate of the state of a given {@link Item} between two points in time.
* The default {@link PersistenceService} is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the item to get the evolution rate value for
* @param begin the beginning point in time
* @param end the end point in time
@@ -2794,6 +3006,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* This method has been deprecated and {@link #evolutionRateSince(Item, ZonedDateTime, String)} should be used
* instead.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the evolution rate value for
* @param timestamp the point in time from which to compute the evolution rate
* @param serviceId the name of the {@link PersistenceService} to use
@@ -2815,6 +3031,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* Gets the evolution rate of the state of a given {@link Item} since a certain point in time.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the evolution rate value for
* @param timestamp the point in time from which to compute the evolution rate
* @param serviceId the name of the {@link PersistenceService} to use
@@ -2834,6 +3054,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* Gets the evolution rate of the state of a given {@link Item} until a certain point in time.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the evolution rate value for
* @param timestamp the point in time to which to compute the evolution rate
* @param serviceId the name of the {@link PersistenceService} to use
@@ -2856,6 +3080,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* This method has been deprecated and {@link #evolutionRateBetween(Item, ZonedDateTime, ZonedDateTime, String)}
* should be used instead.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the evolution rate value for
* @param begin the beginning point in time
* @param end the end point in time
@@ -2879,6 +3107,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
* Gets the evolution rate of the state of a given {@link Item} between two points in time.
* The {@link PersistenceService} identified by the serviceId
is used.
*
+ * Note: If the {@link Item} has a dimension, the calculation will be done using the {@link Item}'s
+ * configured unit.
+ * For temperatures, this will give different results for different configured units.
+ *
* @param item the {@link Item} to get the evolution rate value for
* @param begin the beginning point in time
* @param end the end point in time
@@ -2918,10 +3150,10 @@ private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Ite
}
if (begin == null && end != null && end.isAfter(ZonedDateTime.now())) {
- valueStart = getItemValue(item);
+ valueStart = getItemValue(item, unit);
}
if (begin != null && end == null && begin.isBefore(ZonedDateTime.now())) {
- valueStop = getItemValue(item);
+ valueStop = getItemValue(item, unit);
}
if (valueStart != null && valueStop != null && !valueStart.equals(DecimalType.ZERO)) {
@@ -3487,16 +3719,12 @@ private static void internalRemoveAllStatesBetween(Item item, @Nullable ZonedDat
return null;
}
- private static @Nullable DecimalType getItemValue(Item item) {
- Item baseItem = item instanceof GroupItem groupItem ? groupItem.getBaseItem() : item;
- if (baseItem instanceof NumberItem numberItem) {
- Unit> unit = numberItem.getUnit();
- if (unit != null) {
- QuantityType> qt = item.getStateAs(QuantityType.class);
- qt = (qt != null) ? qt.toUnit(unit) : qt;
- if (qt != null) {
- return new DecimalType(qt.toBigDecimal());
- }
+ private static @Nullable DecimalType getItemValue(Item item, @Nullable Unit> unit) {
+ if (unit != null) {
+ QuantityType> qt = item.getStateAs(QuantityType.class);
+ qt = (qt != null) ? qt.toUnit(unit) : qt;
+ if (qt != null) {
+ return new DecimalType(qt.toBigDecimal());
}
}
return item.getStateAs(DecimalType.class);
diff --git a/bundles/org.openhab.core.persistence/src/test/java/org/openhab/core/persistence/extensions/PersistenceExtensionsTest.java b/bundles/org.openhab.core.persistence/src/test/java/org/openhab/core/persistence/extensions/PersistenceExtensionsTest.java
index b6c7ab00e5e..d2dfe189443 100644
--- a/bundles/org.openhab.core.persistence/src/test/java/org/openhab/core/persistence/extensions/PersistenceExtensionsTest.java
+++ b/bundles/org.openhab.core.persistence/src/test/java/org/openhab/core/persistence/extensions/PersistenceExtensionsTest.java
@@ -45,9 +45,11 @@
import org.openhab.core.items.ItemRegistry;
import org.openhab.core.items.ItemUtil;
import org.openhab.core.library.CoreItemFactory;
+import org.openhab.core.library.dimension.EnergyPrice;
import org.openhab.core.library.types.ArithmeticGroupFunction;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.CurrencyUnits;
import org.openhab.core.library.unit.SIUnits;
import org.openhab.core.library.unit.Units;
import org.openhab.core.persistence.HistoricItem;
@@ -70,6 +72,7 @@
* @author Mark Herwege - Implement aliases
* @author Mark Herwege - Add Riemann sum methods
* @author Mark Herwege - Make tests less impacted by the current time for slow builds, improves test reliability
+ * @author Mark Herwege - use base unit for calculations and results
*/
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@@ -80,8 +83,7 @@ public class PersistenceExtensionsTest {
public static final String TEST_QUANTITY_NUMBER = "testQuantityNumber";
public static final String TEST_GROUP_QUANTITY_NUMBER = "testGroupQuantityNumber";
public static final String TEST_SWITCH = "testSwitch";
-
- public static final double KELVIN_OFFSET = 273.15;
+ public static final String TEST_ENERGYPRICE_QUANTITY_NUMBER = "testEnergyPriceQuantityItem";
private @Mock @NonNullByDefault({}) ItemRegistry itemRegistryMock;
private @Mock @NonNullByDefault({}) UnitProvider unitProviderMock;
@@ -89,17 +91,22 @@ public class PersistenceExtensionsTest {
private @Mock @NonNullByDefault({}) PersistenceServiceConfigurationRegistry persistenceServiceConfigurationRegistryMock;
- private @NonNullByDefault({}) GenericItem numberItem, quantityItem, groupQuantityItem, switchItem;
+ private @NonNullByDefault({}) GenericItem numberItem, quantityItem, groupQuantityItem, switchItem,
+ energyPriceQuantityItem;
@BeforeEach
public void setUp() {
when(unitProviderMock.getUnit(Temperature.class)).thenReturn(SIUnits.CELSIUS);
+ when(unitProviderMock.getUnit(EnergyPrice.class)).thenReturn(CurrencyUnits.BASE_ENERGY_PRICE);
CoreItemFactory itemFactory = new CoreItemFactory(unitProviderMock);
numberItem = itemFactory.createItem(CoreItemFactory.NUMBER, TEST_NUMBER);
quantityItem = itemFactory.createItem(CoreItemFactory.NUMBER + ItemUtil.EXTENSION_SEPARATOR + "Temperature",
TEST_QUANTITY_NUMBER);
switchItem = itemFactory.createItem(CoreItemFactory.SWITCH, TEST_SWITCH);
+ energyPriceQuantityItem = itemFactory.createItem(
+ CoreItemFactory.NUMBER + ItemUtil.EXTENSION_SEPARATOR + "EnergyPrice",
+ TEST_ENERGYPRICE_QUANTITY_NUMBER);
GenericItem baseItem = itemFactory
.createItem(CoreItemFactory.NUMBER + ItemUtil.EXTENSION_SEPARATOR + "Temperature", "testGroupBaseItem");
@@ -111,11 +118,13 @@ public void setUp() {
quantityItem.setState(new QuantityType(STATE, SIUnits.CELSIUS));
groupQuantityItem.setState(new QuantityType(STATE, SIUnits.CELSIUS));
switchItem.setState(SWITCH_STATE);
+ energyPriceQuantityItem.setState(new QuantityType(STATE, CurrencyUnits.BASE_ENERGY_PRICE));
when(itemRegistryMock.get(TEST_NUMBER)).thenReturn(numberItem);
when(itemRegistryMock.get(TEST_QUANTITY_NUMBER)).thenReturn(quantityItem);
when(itemRegistryMock.get(TEST_SWITCH)).thenReturn(switchItem);
when(itemRegistryMock.get(TEST_GROUP_QUANTITY_NUMBER)).thenReturn(groupQuantityItem);
+ when(itemRegistryMock.get(TEST_ENERGYPRICE_QUANTITY_NUMBER)).thenReturn(energyPriceQuantityItem);
when(persistenceServiceConfigurationRegistryMock.get(anyString())).thenReturn(null);
when(timeZoneProviderMock.getTimeZone()).thenReturn(ZoneId.systemDefault());
@@ -341,6 +350,15 @@ public void testPersistedStateOnOffType() {
assertEquals(switchValue(SWITCH_ON_INTERMEDIATE_3), historicItem.getState());
}
+ @Test
+ public void testPersistedStateEnergyPriceQuantityType() {
+ HistoricItem historicItem = PersistenceExtensions.persistedState(energyPriceQuantityItem,
+ ZonedDateTime.of(HISTORIC_END, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
+ assertNotNull(historicItem);
+ assertThat(historicItem.getState(), is(instanceOf(QuantityType.class)));
+ assertEquals(new QuantityType<>(value(HISTORIC_END), CurrencyUnits.BASE_ENERGY_PRICE), historicItem.getState());
+ }
+
@Test
public void testMaximumSinceDecimalType() {
HistoricItem historicItem = PersistenceExtensions.maximumSince(numberItem,
@@ -628,6 +646,17 @@ public void testMaximumUntilOnOffType() {
assertNull(historicItem);
}
+ @Test
+ public void testMaximumBetweenEnergyPriceQuantityType() {
+ HistoricItem historicItem = PersistenceExtensions.maximumBetween(energyPriceQuantityItem,
+ ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
+ ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
+ assertNotNull(historicItem);
+ assertThat(historicItem.getState(), is(instanceOf(QuantityType.class)));
+ assertThat(historicItem.getState(),
+ is(new QuantityType<>(value(HISTORIC_INTERMEDIATE_VALUE_2), CurrencyUnits.BASE_ENERGY_PRICE)));
+ }
+
@Test
public void testMinimumSinceDecimalType() {
HistoricItem historicItem = PersistenceExtensions.minimumSince(numberItem,
@@ -889,6 +918,17 @@ public void testMinimumSinceOnOffType() {
assertNull(historicItem);
}
+ @Test
+ public void testMinimumBetweenEnergyPriceQuantityType() {
+ HistoricItem historicItem = PersistenceExtensions.minimumBetween(energyPriceQuantityItem,
+ ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
+ ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
+ assertNotNull(historicItem);
+ assertThat(historicItem.getState(), is(instanceOf(QuantityType.class)));
+ assertThat(historicItem.getState(),
+ is(new QuantityType<>(value(HISTORIC_INTERMEDIATE_VALUE_1), CurrencyUnits.BASE_ENERGY_PRICE)));
+ }
+
@Test
public void testVarianceSinceDecimalType() {
ZonedDateTime startStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0,
@@ -994,7 +1034,7 @@ public void testVarianceSinceQuantityType() {
QuantityType> qt = variance.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN.multiply(Units.KELVIN), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(SIUnits.CELSIUS), qt.getUnit());
// default persistence service
variance = PersistenceExtensions.varianceSince(quantityItem, startStored);
@@ -1017,7 +1057,7 @@ public void testVarianceUntilQuantityType() {
QuantityType> qt = variance.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN.multiply(Units.KELVIN), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(SIUnits.CELSIUS), qt.getUnit());
// default persistence service
variance = PersistenceExtensions.varianceUntil(quantityItem, endStored);
@@ -1039,7 +1079,7 @@ public void testVarianceBetweenQuantityType() {
QuantityType> qt = variance.as(QuantityType.class);
assertNotNull(qt);
assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
- assertEquals(Units.KELVIN.multiply(Units.KELVIN), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(SIUnits.CELSIUS), qt.getUnit());
startStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
endStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_4, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
@@ -1052,7 +1092,7 @@ public void testVarianceBetweenQuantityType() {
qt = variance.as(QuantityType.class);
assertNotNull(qt);
assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
- assertEquals(Units.KELVIN.multiply(Units.KELVIN), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(SIUnits.CELSIUS), qt.getUnit());
startStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
endStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
@@ -1067,7 +1107,7 @@ public void testVarianceBetweenQuantityType() {
qt = variance.as(QuantityType.class);
assertNotNull(qt);
assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
- assertEquals(Units.KELVIN.multiply(Units.KELVIN), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(SIUnits.CELSIUS), qt.getUnit());
// default persistence service
variance = PersistenceExtensions.varianceBetween(quantityItem, startStored, endStored);
@@ -1089,7 +1129,7 @@ public void testVarianceSinceGroupQuantityType() {
QuantityType> qt = variance.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN.multiply(Units.KELVIN), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(SIUnits.CELSIUS), qt.getUnit());
// default persistence service
variance = PersistenceExtensions.varianceSince(groupQuantityItem, startStored);
@@ -1112,7 +1152,7 @@ public void testVarianceUntilGroupQuantityType() {
QuantityType> qt = variance.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN.multiply(Units.KELVIN), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(SIUnits.CELSIUS), qt.getUnit());
// default persistence service
variance = PersistenceExtensions.varianceUntil(groupQuantityItem, endStored);
@@ -1134,7 +1174,7 @@ public void testVarianceBetweenGroupQuantityType() {
QuantityType> qt = variance.as(QuantityType.class);
assertNotNull(qt);
assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
- assertEquals(Units.KELVIN.multiply(Units.KELVIN), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(SIUnits.CELSIUS), qt.getUnit());
startStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
endStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_4, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
@@ -1147,7 +1187,7 @@ public void testVarianceBetweenGroupQuantityType() {
qt = variance.as(QuantityType.class);
assertNotNull(qt);
assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
- assertEquals(Units.KELVIN.multiply(Units.KELVIN), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(SIUnits.CELSIUS), qt.getUnit());
startStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
endStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
@@ -1162,13 +1202,34 @@ public void testVarianceBetweenGroupQuantityType() {
qt = variance.as(QuantityType.class);
assertNotNull(qt);
assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
- assertEquals(Units.KELVIN.multiply(Units.KELVIN), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(SIUnits.CELSIUS), qt.getUnit());
// default persistence service
variance = PersistenceExtensions.varianceBetween(groupQuantityItem, startStored, endStored);
assertNull(variance);
}
+ @Test
+ public void testVarianceBetweenEnergyPriceQuantityType() {
+ ZonedDateTime startStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0,
+ ZoneId.systemDefault());
+ ZonedDateTime endStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0,
+ ZoneId.systemDefault());
+ double expectedAverage1 = testAverage(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2);
+
+ double expected = IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2)
+ .mapToDouble(i -> Double.valueOf(i)).map(d -> Math.pow(d - expectedAverage1, 2)).sum()
+ / (HISTORIC_INTERMEDIATE_VALUE_2 - HISTORIC_INTERMEDIATE_VALUE_1 + 1);
+
+ State variance = PersistenceExtensions.varianceBetween(energyPriceQuantityItem, startStored, endStored,
+ SERVICE_ID);
+ assertNotNull(variance);
+ QuantityType> qt = variance.as(QuantityType.class);
+ assertNotNull(qt);
+ assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
+ assertEquals(CurrencyUnits.BASE_ENERGY_PRICE.multiply(CurrencyUnits.BASE_ENERGY_PRICE), qt.getUnit());
+ }
+
@Test
public void testDeviationSinceDecimalType() {
ZonedDateTime startStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0,
@@ -1274,7 +1335,7 @@ public void testDeviationSinceQuantityType() {
QuantityType> qt = deviation.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
// default persistence service
deviation = PersistenceExtensions.deviationSince(quantityItem, startStored);
@@ -1297,7 +1358,7 @@ public void testDeviationUntilQuantityType() {
QuantityType> qt = deviation.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
// default persistence service
deviation = PersistenceExtensions.deviationUntil(quantityItem, endStored);
@@ -1319,7 +1380,7 @@ public void testDeviationBetweenQuantityType() {
QuantityType> qt = deviation.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
startStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
endStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_4, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
@@ -1332,7 +1393,7 @@ public void testDeviationBetweenQuantityType() {
qt = deviation.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
startStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
endStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
@@ -1347,7 +1408,7 @@ public void testDeviationBetweenQuantityType() {
qt = deviation.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
// default persistence service
deviation = PersistenceExtensions.deviationBetween(quantityItem, startStored, endStored);
@@ -1369,7 +1430,7 @@ public void testDeviationSinceGroupQuantityType() {
QuantityType> qt = deviation.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
// default persistence service
deviation = PersistenceExtensions.deviationSince(groupQuantityItem, startStored);
@@ -1392,7 +1453,7 @@ public void testDeviationUntilGroupQuantityType() {
QuantityType> qt = deviation.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
// default persistence service
deviation = PersistenceExtensions.deviationUntil(groupQuantityItem, endStored);
@@ -1414,7 +1475,7 @@ public void testDeviationBetweenGroupQuantityType() {
QuantityType> qt = deviation.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
startStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
endStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_4, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
@@ -1427,7 +1488,7 @@ public void testDeviationBetweenGroupQuantityType() {
qt = deviation.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
startStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
endStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
@@ -1442,13 +1503,33 @@ public void testDeviationBetweenGroupQuantityType() {
qt = deviation.as(QuantityType.class);
assertNotNull(qt);
assertEquals(expected, qt.doubleValue(), 0.01);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
// default persistence service
deviation = PersistenceExtensions.deviationBetween(groupQuantityItem, startStored, endStored);
assertNull(deviation);
}
+ @Test
+ public void testDeviationBetweenEnergyPriceQuantityType() {
+ ZonedDateTime startStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0,
+ ZoneId.systemDefault());
+ ZonedDateTime endStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0,
+ ZoneId.systemDefault());
+ double expectedAverage = testAverage(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2);
+
+ double expected = Math.sqrt(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2)
+ .mapToDouble(i -> Double.parseDouble(Integer.toString(i))).map(d -> Math.pow(d - expectedAverage, 2))
+ .sum() / (HISTORIC_INTERMEDIATE_VALUE_2 - HISTORIC_INTERMEDIATE_VALUE_1 + 1));
+ State deviation = PersistenceExtensions.deviationBetween(energyPriceQuantityItem, startStored, endStored,
+ SERVICE_ID);
+ assertNotNull(deviation);
+ QuantityType> qt = deviation.as(QuantityType.class);
+ assertNotNull(qt);
+ assertEquals(expected, qt.doubleValue(), 0.01);
+ assertEquals(CurrencyUnits.BASE_ENERGY_PRICE, qt.getUnit());
+ }
+
@Test
public void testRiemannSumBetweenDecimalType() {
RiemannType type = RiemannType.LEFT;
@@ -1593,33 +1674,33 @@ public void testRiemannSumBetweenQuantityType() {
ZoneId.systemDefault());
ZonedDateTime endStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0,
ZoneId.systemDefault());
- double expected = testRiemannSumCelsius(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2, type);
+ double expected = testRiemannSum(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2, type);
State sum = PersistenceExtensions.riemannSumBetween(quantityItem, beginStored, endStored, type, SERVICE_ID);
assertNotNull(sum);
QuantityType> qt = sum.as(QuantityType.class);
assertNotNull(qt);
assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
- assertEquals(Units.KELVIN.multiply(Units.SECOND), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(Units.SECOND), qt.getUnit());
beginStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
endStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_4, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
- expected = testRiemannSumCelsius(FUTURE_INTERMEDIATE_VALUE_3, FUTURE_INTERMEDIATE_VALUE_4, type);
+ expected = testRiemannSum(FUTURE_INTERMEDIATE_VALUE_3, FUTURE_INTERMEDIATE_VALUE_4, type);
sum = PersistenceExtensions.riemannSumBetween(quantityItem, beginStored, endStored, type, SERVICE_ID);
assertNotNull(sum);
qt = sum.as(QuantityType.class);
assertNotNull(qt);
assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
- assertEquals(Units.KELVIN.multiply(Units.SECOND), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(Units.SECOND), qt.getUnit());
beginStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
endStored = ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
- expected = testRiemannSumCelsius(HISTORIC_INTERMEDIATE_VALUE_1, FUTURE_INTERMEDIATE_VALUE_3, type);
+ expected = testRiemannSum(HISTORIC_INTERMEDIATE_VALUE_1, FUTURE_INTERMEDIATE_VALUE_3, type);
sum = PersistenceExtensions.riemannSumBetween(quantityItem, beginStored, endStored, type, SERVICE_ID);
assertNotNull(sum);
qt = sum.as(QuantityType.class);
assertNotNull(qt);
assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
- assertEquals(Units.KELVIN.multiply(Units.SECOND), qt.getUnit());
+ assertEquals(SIUnits.CELSIUS.multiply(Units.SECOND), qt.getUnit());
// default persistence service
sum = PersistenceExtensions.riemannSumBetween(quantityItem, beginStored, endStored, type);
@@ -1718,6 +1799,25 @@ public void testRiemannSumBetweenZeroDuration() {
assertThat(dt.doubleValue(), is(closeTo(0, 0.01)));
}
+ @Test
+ public void testRiemannSumBetweenEnergyPriceQuantityType() {
+ for (RiemannType type : RiemannType.values()) {
+ ZonedDateTime beginStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0,
+ ZoneId.systemDefault());
+ ZonedDateTime endStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0,
+ ZoneId.systemDefault());
+ double expected = testRiemannSum(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2, type);
+ State sum = PersistenceExtensions.riemannSumBetween(energyPriceQuantityItem, beginStored, endStored, type,
+ SERVICE_ID);
+
+ assertNotNull(sum);
+ QuantityType> qt = sum.as(QuantityType.class);
+ assertNotNull(qt);
+ assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
+ assertEquals(CurrencyUnits.BASE_ENERGY_PRICE.multiply(Units.SECOND), qt.getUnit());
+ }
+ }
+
@Test
public void testAverageSinceDecimalType() {
ZonedDateTime start = ZonedDateTime.of(BEFORE_START, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
@@ -2086,6 +2186,23 @@ public void testAverageBetweenZeroDuration() {
assertEquals(SIUnits.CELSIUS, qt.getUnit());
}
+ @Test
+ public void testAverageBetweenEnergyPriceQuantityType() {
+ ZonedDateTime beginStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0,
+ ZoneId.systemDefault());
+ ZonedDateTime endStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0,
+ ZoneId.systemDefault());
+ double expected = testAverage(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2);
+ State average = PersistenceExtensions.averageBetween(energyPriceQuantityItem, beginStored, endStored,
+ SERVICE_ID);
+
+ assertNotNull(average);
+ QuantityType> qt = average.as(QuantityType.class);
+ assertNotNull(qt);
+ assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
+ assertEquals(CurrencyUnits.BASE_ENERGY_PRICE, qt.getUnit());
+ }
+
@Test
public void testMedianSinceDecimalType() {
ZonedDateTime start = ZonedDateTime.of(BEFORE_START, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
@@ -2331,6 +2448,22 @@ public void testMedianBetweenZeroDuration() {
assertEquals(SIUnits.CELSIUS, qt.getUnit());
}
+ @Test
+ public void testMedianBetweenEnergyPriceQuantityType() {
+ ZonedDateTime beginStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0,
+ ZoneId.systemDefault());
+ ZonedDateTime endStored = ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0,
+ ZoneId.systemDefault());
+ double expected = testMedian(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2);
+ State median = PersistenceExtensions.medianBetween(energyPriceQuantityItem, beginStored, endStored, SERVICE_ID);
+
+ assertNotNull(median);
+ QuantityType> qt = median.as(QuantityType.class);
+ assertNotNull(qt);
+ assertThat(qt.doubleValue(), is(closeTo(expected, 0.01)));
+ assertEquals(CurrencyUnits.BASE_ENERGY_PRICE, qt.getUnit());
+ }
+
@Test
public void testSumSinceDecimalType() {
State sum = PersistenceExtensions.sumSince(numberItem,
@@ -2413,18 +2546,16 @@ public void testSumSinceQuantityType() {
assertNotNull(sum);
QuantityType> qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(IntStream.rangeClosed(HISTORIC_START, HISTORIC_END).sum()
- + (HISTORIC_END - HISTORIC_START + 1) * KELVIN_OFFSET, qt.doubleValue(), 0.001);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(IntStream.rangeClosed(HISTORIC_START, HISTORIC_END).sum(), qt.doubleValue(), 0.001);
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
sum = PersistenceExtensions.sumSince(quantityItem,
ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
assertNotNull(sum);
qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_END).sum()
- + (HISTORIC_END - HISTORIC_INTERMEDIATE_VALUE_1 + 1) * KELVIN_OFFSET, qt.doubleValue(), 0.001);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_END).sum(), qt.doubleValue(), 0.001);
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
// default persistence service
sum = PersistenceExtensions.sumSince(quantityItem,
@@ -2439,9 +2570,8 @@ public void testSumUntilQuantityType() {
assertNotNull(sum);
QuantityType> qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(IntStream.rangeClosed(FUTURE_START, FUTURE_INTERMEDIATE_VALUE_3).sum()
- + (FUTURE_INTERMEDIATE_VALUE_3 - FUTURE_START + 1) * KELVIN_OFFSET, qt.doubleValue(), 0.001);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(IntStream.rangeClosed(FUTURE_START, FUTURE_INTERMEDIATE_VALUE_3).sum(), qt.doubleValue(), 0.001);
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
// default persistence service
sum = PersistenceExtensions.sumSince(quantityItem,
@@ -2451,45 +2581,38 @@ public void testSumUntilQuantityType() {
@Test
public void testSumBetweenQuantityType() {
- State sum = PersistenceExtensions.sumBetween(groupQuantityItem,
+ State sum = PersistenceExtensions.sumBetween(quantityItem,
ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
assertNotNull(sum);
QuantityType> qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(
- IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2).sum()
- + (HISTORIC_INTERMEDIATE_VALUE_2 - HISTORIC_INTERMEDIATE_VALUE_1 + 1) * KELVIN_OFFSET,
+ assertEquals(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2).sum(),
qt.doubleValue(), 0.001);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
- sum = PersistenceExtensions.sumBetween(groupQuantityItem,
+ sum = PersistenceExtensions.sumBetween(quantityItem,
ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_4, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
assertNotNull(sum);
qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(
- IntStream.rangeClosed(FUTURE_INTERMEDIATE_VALUE_3, FUTURE_INTERMEDIATE_VALUE_4).sum()
- + (FUTURE_INTERMEDIATE_VALUE_4 - FUTURE_INTERMEDIATE_VALUE_3 + 1) * KELVIN_OFFSET,
+ assertEquals(IntStream.rangeClosed(FUTURE_INTERMEDIATE_VALUE_3, FUTURE_INTERMEDIATE_VALUE_4).sum(),
qt.doubleValue(), 0.001);
- sum = PersistenceExtensions.sumBetween(groupQuantityItem,
+ sum = PersistenceExtensions.sumBetween(quantityItem,
ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
assertNotNull(sum);
qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(IntStream
- .concat(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_END),
- IntStream.rangeClosed(FUTURE_START, FUTURE_INTERMEDIATE_VALUE_3))
- .sum()
- + (HISTORIC_END - HISTORIC_INTERMEDIATE_VALUE_1 + FUTURE_INTERMEDIATE_VALUE_3 - FUTURE_START + 2)
- * KELVIN_OFFSET,
+ assertEquals(
+ IntStream.concat(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_END),
+ IntStream.rangeClosed(FUTURE_START, FUTURE_INTERMEDIATE_VALUE_3)).sum(),
qt.doubleValue(), 0.001);
// default persistence service
- sum = PersistenceExtensions.sumBetween(groupQuantityItem,
+ sum = PersistenceExtensions.sumBetween(quantityItem,
ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()));
@@ -2503,18 +2626,16 @@ public void testSumSinceGroupQuantityType() {
assertNotNull(sum);
QuantityType> qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(IntStream.rangeClosed(HISTORIC_START, HISTORIC_END).sum()
- + (HISTORIC_END - HISTORIC_START + 1) * KELVIN_OFFSET, qt.doubleValue(), 0.001);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(IntStream.rangeClosed(HISTORIC_START, HISTORIC_END).sum(), qt.doubleValue(), 0.001);
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
sum = PersistenceExtensions.sumSince(groupQuantityItem,
ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
assertNotNull(sum);
qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_END).sum()
- + (HISTORIC_END - HISTORIC_INTERMEDIATE_VALUE_1 + 1) * KELVIN_OFFSET, qt.doubleValue(), 0.001);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_END).sum(), qt.doubleValue(), 0.001);
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
// default persistence service
sum = PersistenceExtensions.sumSince(groupQuantityItem,
@@ -2529,9 +2650,8 @@ public void testSumUntilGroupQuantityType() {
assertNotNull(sum);
QuantityType> qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(IntStream.rangeClosed(FUTURE_START, FUTURE_INTERMEDIATE_VALUE_3).sum()
- + (FUTURE_INTERMEDIATE_VALUE_3 - FUTURE_START + 1) * KELVIN_OFFSET, qt.doubleValue(), 0.001);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(IntStream.rangeClosed(FUTURE_START, FUTURE_INTERMEDIATE_VALUE_3).sum(), qt.doubleValue(), 0.001);
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
// default persistence service
sum = PersistenceExtensions.sumSince(groupQuantityItem,
@@ -2547,11 +2667,9 @@ public void testSumBetweenGroupQuantityType() {
assertNotNull(sum);
QuantityType> qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(
- IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2).sum()
- + (HISTORIC_INTERMEDIATE_VALUE_2 - HISTORIC_INTERMEDIATE_VALUE_1 + 1) * KELVIN_OFFSET,
+ assertEquals(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2).sum(),
qt.doubleValue(), 0.001);
- assertEquals(Units.KELVIN, qt.getUnit());
+ assertEquals(SIUnits.CELSIUS, qt.getUnit());
sum = PersistenceExtensions.sumBetween(groupQuantityItem,
ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
@@ -2559,9 +2677,7 @@ public void testSumBetweenGroupQuantityType() {
assertNotNull(sum);
qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(
- IntStream.rangeClosed(FUTURE_INTERMEDIATE_VALUE_3, FUTURE_INTERMEDIATE_VALUE_4).sum()
- + (FUTURE_INTERMEDIATE_VALUE_4 - FUTURE_INTERMEDIATE_VALUE_3 + 1) * KELVIN_OFFSET,
+ assertEquals(IntStream.rangeClosed(FUTURE_INTERMEDIATE_VALUE_3, FUTURE_INTERMEDIATE_VALUE_4).sum(),
qt.doubleValue(), 0.001);
sum = PersistenceExtensions.sumBetween(groupQuantityItem,
@@ -2570,12 +2686,9 @@ public void testSumBetweenGroupQuantityType() {
assertNotNull(sum);
qt = sum.as(QuantityType.class);
assertNotNull(qt);
- assertEquals(IntStream
- .concat(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_END),
- IntStream.rangeClosed(FUTURE_START, FUTURE_INTERMEDIATE_VALUE_3))
- .sum()
- + (HISTORIC_END - HISTORIC_INTERMEDIATE_VALUE_1 + FUTURE_INTERMEDIATE_VALUE_3 - FUTURE_START + 2)
- * KELVIN_OFFSET,
+ assertEquals(
+ IntStream.concat(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_END),
+ IntStream.rangeClosed(FUTURE_START, FUTURE_INTERMEDIATE_VALUE_3)).sum(),
qt.doubleValue(), 0.001);
// default persistence service
@@ -2586,6 +2699,19 @@ public void testSumBetweenGroupQuantityType() {
assertNull(sum);
}
+ @Test
+ public void testSumBetweenEnergyPriceQuantityType() {
+ State sum = PersistenceExtensions.sumBetween(energyPriceQuantityItem,
+ ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
+ ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
+ assertNotNull(sum);
+ QuantityType> qt = sum.as(QuantityType.class);
+ assertNotNull(qt);
+ assertEquals(IntStream.rangeClosed(HISTORIC_INTERMEDIATE_VALUE_1, HISTORIC_INTERMEDIATE_VALUE_2).sum(),
+ qt.doubleValue(), 0.001);
+ assertEquals(CurrencyUnits.BASE_ENERGY_PRICE, qt.getUnit());
+ }
+
@Test
public void testLastUpdate() {
ZonedDateTime lastUpdate = PersistenceExtensions.lastUpdate(numberItem, SERVICE_ID);
@@ -2752,6 +2878,15 @@ public void testDeltaBetween() {
assertEquals(HISTORIC_INTERMEDIATE_VALUE_2 - HISTORIC_INTERMEDIATE_VALUE_1, qt.doubleValue(), 0.001);
assertEquals(SIUnits.CELSIUS, qt.getUnit());
+ delta = PersistenceExtensions.deltaBetween(energyPriceQuantityItem,
+ ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
+ ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
+ assertNotNull(delta);
+ qt = delta.as(QuantityType.class);
+ assertNotNull(qt);
+ assertEquals(HISTORIC_INTERMEDIATE_VALUE_2 - HISTORIC_INTERMEDIATE_VALUE_1, qt.doubleValue(), 0.001);
+ assertEquals(CurrencyUnits.BASE_ENERGY_PRICE, qt.getUnit());
+
delta = PersistenceExtensions.deltaBetween(numberItem,
ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_4, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
@@ -2883,6 +3018,15 @@ public void testEvolutionRateBetween() {
100.0 * (HISTORIC_INTERMEDIATE_VALUE_2 - HISTORIC_INTERMEDIATE_VALUE_1) / HISTORIC_INTERMEDIATE_VALUE_1,
0.001)));
+ rate = PersistenceExtensions.evolutionRateBetween(energyPriceQuantityItem,
+ ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_1, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
+ ZonedDateTime.of(HISTORIC_INTERMEDIATE_VALUE_2, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
+ assertNotNull(rate);
+ // ((now - then) / then) * 100
+ assertThat(rate.doubleValue(), is(closeTo(
+ 100.0 * (HISTORIC_INTERMEDIATE_VALUE_2 - HISTORIC_INTERMEDIATE_VALUE_1) / HISTORIC_INTERMEDIATE_VALUE_1,
+ 0.001)));
+
rate = PersistenceExtensions.evolutionRateBetween(numberItem,
ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_3, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
ZonedDateTime.of(FUTURE_INTERMEDIATE_VALUE_4, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), SERVICE_ID);
diff --git a/bundles/org.openhab.core.persistence/src/test/java/org/openhab/core/persistence/extensions/TestPersistenceService.java b/bundles/org.openhab.core.persistence/src/test/java/org/openhab/core/persistence/extensions/TestPersistenceService.java
index ff39cdc281a..2196a2d8161 100644
--- a/bundles/org.openhab.core.persistence/src/test/java/org/openhab/core/persistence/extensions/TestPersistenceService.java
+++ b/bundles/org.openhab.core.persistence/src/test/java/org/openhab/core/persistence/extensions/TestPersistenceService.java
@@ -51,6 +51,7 @@
* @author Kai Kreuzer - Initial contribution
* @author Mark Herwege - Allow future values
* @author Mark Herwege - Adapt test expected value logic for Riemann sums
+ * @author Mark Herwege - use base unit for calculations and results
*/
@NonNullByDefault
public class TestPersistenceService implements QueryablePersistenceService {
@@ -90,8 +91,6 @@ public class TestPersistenceService implements QueryablePersistenceService {
static final int AFTER_END = BASE_VALUE + 85; // 2110
static final DecimalType STATE = new DecimalType(HISTORIC_END);
- static final double KELVIN_OFFSET = 273.15;
-
private final ItemRegistry itemRegistry;
public TestPersistenceService(ItemRegistry itemRegistry) {
@@ -241,33 +240,20 @@ static OnOffType switchValue(int hour) {
}
static DecimalType value(long year) {
- return value(year, false);
- }
-
- private static DecimalType value(long year, boolean kelvinOffset) {
if (year < HISTORIC_START) {
return DecimalType.ZERO;
} else if (year <= HISTORIC_END) {
- return new DecimalType(year + (kelvinOffset ? KELVIN_OFFSET : 0));
+ return new DecimalType(year);
} else if (year < FUTURE_START) {
- return new DecimalType(HISTORIC_END + (kelvinOffset ? KELVIN_OFFSET : 0));
+ return new DecimalType(HISTORIC_END);
} else if (year <= FUTURE_END) {
- return new DecimalType(year + (kelvinOffset ? KELVIN_OFFSET : 0));
+ return new DecimalType(year);
} else {
- return new DecimalType(FUTURE_END + (kelvinOffset ? KELVIN_OFFSET : 0));
+ return new DecimalType(FUTURE_END);
}
}
static double testRiemannSum(@Nullable Integer beginYear, @Nullable Integer endYear, RiemannType type) {
- return testRiemannSum(beginYear, endYear, type, false);
- }
-
- static double testRiemannSumCelsius(@Nullable Integer beginYear, @Nullable Integer endYear, RiemannType type) {
- return testRiemannSum(beginYear, endYear, type, true);
- }
-
- private static double testRiemannSum(@Nullable Integer beginYear, @Nullable Integer endYear, RiemannType type,
- boolean kelvinOffset) {
ZonedDateTime now = ZonedDateTime.now();
int begin = beginYear != null ? (beginYear < HISTORIC_START ? HISTORIC_START : beginYear) : now.getYear() + 1;
int end = endYear != null ? endYear : now.getYear();
@@ -284,7 +270,7 @@ private static double testRiemannSum(@Nullable Integer beginYear, @Nullable Inte
}
while (index < end) {
int bucketStart = index;
- double value = value(index, kelvinOffset).doubleValue();
+ double value = value(index).doubleValue();
while ((index < end - 1) && (value(index).longValue() == value(index + 1).longValue())) {
index++;
}
@@ -314,7 +300,7 @@ private static double testRiemannSum(@Nullable Integer beginYear, @Nullable Inte
index++;
}
index++;
- double value = value(index, kelvinOffset).doubleValue();
+ double value = value(index).doubleValue();
duration += Duration
.between(ZonedDateTime.of(bucketStart, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
ZonedDateTime.of(index, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()))
@@ -336,12 +322,12 @@ private static double testRiemannSum(@Nullable Integer beginYear, @Nullable Inte
}
while (index < end) {
int bucketStart = index;
- double value = value(index, kelvinOffset).doubleValue();
+ double value = value(index).doubleValue();
while ((index < end - 1) && (value(index).longValue() == value(index + 1).longValue())) {
index++;
}
index++;
- value = (value + value(index, kelvinOffset).doubleValue()) / 2.0;
+ value = (value + value(index).doubleValue()) / 2.0;
duration += Duration
.between(ZonedDateTime.of(bucketStart, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
ZonedDateTime.of(index, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()))
@@ -358,7 +344,7 @@ private static double testRiemannSum(@Nullable Integer beginYear, @Nullable Inte
case MIDPOINT:
int nextIndex = begin;
boolean startBucket = true;
- double startValue = value(begin, kelvinOffset).doubleValue();
+ double startValue = value(begin).doubleValue();
if (beginYear == null) {
duration = Duration.between(now, ZonedDateTime.of(begin, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()))
.toSeconds();
@@ -369,7 +355,7 @@ private static double testRiemannSum(@Nullable Integer beginYear, @Nullable Inte
index++;
}
index++;
- double value = value(index, kelvinOffset).doubleValue();
+ double value = value(index).doubleValue();
duration += Duration
.between(ZonedDateTime.of(bucketStart, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()),
ZonedDateTime.of(index, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()))
@@ -397,7 +383,7 @@ private static double testRiemannSum(@Nullable Integer beginYear, @Nullable Inte
sum += value * (duration + nextDuration) / 2.0;
duration = 0;
}
- double endValue = value(end, kelvinOffset).doubleValue();
+ double endValue = value(end).doubleValue();
long endDuration = nextDuration;
sum += endValue * endDuration / 2.0;
break;