mirror of
https://github.com/danieldemus/openhab-core.git
synced 2026-07-29 12:34:22 +02:00
[persistence] use Instant instead of ZonedDateTime in Riemann sum methods (#5101)
Signed-off-by: Jörg Sautter <joerg.sautter@gmx.net>
This commit is contained in:
+16
-6
@@ -12,6 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.core.persistence;
|
package org.openhab.core.persistence;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -22,7 +24,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.core.persistence.FilterCriteria.Ordering;
|
import org.openhab.core.persistence.FilterCriteria.Ordering;
|
||||||
import org.openhab.core.types.State;
|
import org.openhab.core.types.State;
|
||||||
import org.openhab.core.types.UnDefType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A queryable persistence service which can be used to store and retrieve
|
* A queryable persistence service which can be used to store and retrieve
|
||||||
@@ -65,6 +66,11 @@ public interface QueryablePersistenceService extends PersistenceService {
|
|||||||
FilterCriteria aliasFilter = new FilterCriteria(filter).setItemName(alias);
|
FilterCriteria aliasFilter = new FilterCriteria(filter).setItemName(alias);
|
||||||
return StreamSupport.stream(query(aliasFilter).spliterator(), false).map(hi -> new HistoricItem() {
|
return StreamSupport.stream(query(aliasFilter).spliterator(), false).map(hi -> new HistoricItem() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Instant getInstant() {
|
||||||
|
return hi.getInstant();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ZonedDateTime getTimestamp() {
|
public ZonedDateTime getTimestamp() {
|
||||||
return hi.getTimestamp();
|
return hi.getTimestamp();
|
||||||
@@ -111,8 +117,8 @@ public interface QueryablePersistenceService extends PersistenceService {
|
|||||||
* @return a {@link PersistedItem} or null if the item has not been persisted
|
* @return a {@link PersistedItem} or null if the item has not been persisted
|
||||||
*/
|
*/
|
||||||
default @Nullable PersistedItem persistedItem(String itemName, @Nullable String alias) {
|
default @Nullable PersistedItem persistedItem(String itemName, @Nullable String alias) {
|
||||||
State currentState = UnDefType.NULL;
|
State currentState;
|
||||||
ZonedDateTime lastUpdate = null;
|
Instant lastUpdate;
|
||||||
|
|
||||||
FilterCriteria filter = new FilterCriteria().setItemName(itemName).setEndDate(ZonedDateTime.now())
|
FilterCriteria filter = new FilterCriteria().setItemName(itemName).setEndDate(ZonedDateTime.now())
|
||||||
.setOrdering(Ordering.DESCENDING).setPageSize(1).setPageNumber(0);
|
.setOrdering(Ordering.DESCENDING).setPageSize(1).setPageNumber(0);
|
||||||
@@ -120,19 +126,23 @@ public interface QueryablePersistenceService extends PersistenceService {
|
|||||||
if (it.hasNext()) {
|
if (it.hasNext()) {
|
||||||
HistoricItem historicItem = it.next();
|
HistoricItem historicItem = it.next();
|
||||||
currentState = historicItem.getState();
|
currentState = historicItem.getState();
|
||||||
lastUpdate = historicItem.getTimestamp();
|
lastUpdate = historicItem.getInstant();
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final State state = currentState;
|
final State state = currentState;
|
||||||
final ZonedDateTime lastStateUpdate = lastUpdate;
|
final Instant lastStateUpdate = lastUpdate;
|
||||||
|
|
||||||
return new PersistedItem() {
|
return new PersistedItem() {
|
||||||
|
@Override
|
||||||
|
public Instant getInstant() {
|
||||||
|
return lastStateUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ZonedDateTime getTimestamp() {
|
public ZonedDateTime getTimestamp() {
|
||||||
return lastStateUpdate;
|
return lastStateUpdate.atZone(ZoneId.systemDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+25
-18
@@ -15,6 +15,7 @@ package org.openhab.core.persistence.extensions;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -71,6 +72,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
* @author Mark Herwege - add median methods
|
* @author Mark Herwege - add median methods
|
||||||
* @author Mark Herwege - use item lastChange and lastUpdate methods if not in peristence
|
* @author Mark Herwege - use item lastChange and lastUpdate methods if not in peristence
|
||||||
* @author Mark Herwege - add Riemann sum methods
|
* @author Mark Herwege - add Riemann sum methods
|
||||||
|
* @author Jörg Sautter - use Instant instead of ZonedDateTime in Riemann sum methods
|
||||||
*/
|
*/
|
||||||
@Component(immediate = true)
|
@Component(immediate = true)
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@@ -1926,7 +1928,7 @@ public class PersistenceExtensions {
|
|||||||
|
|
||||||
private static @Nullable BigDecimal average(ZonedDateTime begin, ZonedDateTime end, Iterator<HistoricItem> it,
|
private static @Nullable BigDecimal average(ZonedDateTime begin, ZonedDateTime end, Iterator<HistoricItem> it,
|
||||||
@Nullable Unit<?> unit, @Nullable RiemannType type) {
|
@Nullable Unit<?> unit, @Nullable RiemannType type) {
|
||||||
BigDecimal sum = riemannSum(begin, end, it, unit, type);
|
BigDecimal sum = riemannSum(begin.toInstant(), end.toInstant(), it, unit, type);
|
||||||
BigDecimal totalDuration = BigDecimal.valueOf(Duration.between(begin, end).toMillis());
|
BigDecimal totalDuration = BigDecimal.valueOf(Duration.between(begin, end).toMillis());
|
||||||
if (totalDuration.signum() == 0) {
|
if (totalDuration.signum() == 0) {
|
||||||
return null;
|
return null;
|
||||||
@@ -2195,35 +2197,39 @@ public class PersistenceExtensions {
|
|||||||
Item baseItem = item instanceof GroupItem groupItem ? groupItem.getBaseItem() : item;
|
Item baseItem = item instanceof GroupItem groupItem ? groupItem.getBaseItem() : item;
|
||||||
Unit<?> unit = (baseItem instanceof NumberItem numberItem)
|
Unit<?> unit = (baseItem instanceof NumberItem numberItem)
|
||||||
&& (numberItem.getUnit() instanceof Unit<?> numberItemUnit) ? numberItemUnit.getSystemUnit() : null;
|
&& (numberItem.getUnit() instanceof Unit<?> numberItemUnit) ? numberItemUnit.getSystemUnit() : null;
|
||||||
BigDecimal sum = riemannSum(beginTime, endTime, it, unit, type).scaleByPowerOfTen(-3);
|
BigDecimal sum = riemannSum(beginTime.toInstant(), endTime.toInstant(), it, unit, type).scaleByPowerOfTen(-3);
|
||||||
if (unit != null) {
|
if (unit != null) {
|
||||||
return new QuantityType<>(sum, unit.multiply(Units.SECOND));
|
return new QuantityType<>(sum, unit.multiply(Units.SECOND));
|
||||||
}
|
}
|
||||||
return new DecimalType(sum);
|
return new DecimalType(sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BigDecimal riemannSum(ZonedDateTime begin, ZonedDateTime end, Iterator<HistoricItem> it,
|
private static BigDecimal riemannSum(Instant begin, Instant end, Iterator<HistoricItem> it, @Nullable Unit<?> unit,
|
||||||
@Nullable Unit<?> unit, @Nullable RiemannType type) {
|
@Nullable RiemannType type) {
|
||||||
RiemannType riemannType = type == null ? RiemannType.LEFT : type;
|
RiemannType riemannType = type == null ? RiemannType.LEFT : type;
|
||||||
|
|
||||||
BigDecimal sum = BigDecimal.ZERO;
|
BigDecimal sum = BigDecimal.ZERO;
|
||||||
HistoricItem prevItem = null;
|
HistoricItem prevItem = null;
|
||||||
HistoricItem nextItem = null;
|
HistoricItem nextItem;
|
||||||
DecimalType prevState = null;
|
DecimalType prevState = null;
|
||||||
DecimalType nextState = null;
|
DecimalType nextState;
|
||||||
|
Instant prevInstant = null;
|
||||||
|
Instant nextInstant;
|
||||||
Duration prevDuration = Duration.ZERO;
|
Duration prevDuration = Duration.ZERO;
|
||||||
Duration nextDuration = Duration.ZERO;
|
Duration nextDuration;
|
||||||
|
|
||||||
boolean midpointStartBucket = true; // The start and end buckets for the midpoint calculation should be
|
boolean midpointStartBucket = true; // The start and end buckets for the midpoint calculation should be
|
||||||
// considered for the full length, this flag is used to find the start
|
// considered for the full length, this flag is used to find the start
|
||||||
// bucket
|
// bucket
|
||||||
if ((riemannType == RiemannType.MIDPOINT) && it.hasNext()) {
|
if ((riemannType == RiemannType.MIDPOINT) && it.hasNext()) {
|
||||||
prevItem = it.next();
|
prevItem = it.next();
|
||||||
|
prevInstant = prevItem.getInstant();
|
||||||
prevState = getPersistedValue(prevItem, unit);
|
prevState = getPersistedValue(prevItem, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
nextItem = it.next();
|
nextItem = it.next();
|
||||||
|
nextInstant = nextItem.getInstant();
|
||||||
BigDecimal weight = BigDecimal.ZERO;
|
BigDecimal weight = BigDecimal.ZERO;
|
||||||
BigDecimal value = BigDecimal.ZERO;
|
BigDecimal value = BigDecimal.ZERO;
|
||||||
switch (riemannType) {
|
switch (riemannType) {
|
||||||
@@ -2232,24 +2238,24 @@ public class PersistenceExtensions {
|
|||||||
prevState = getPersistedValue(prevItem, unit);
|
prevState = getPersistedValue(prevItem, unit);
|
||||||
if (prevState != null) {
|
if (prevState != null) {
|
||||||
value = prevState.toBigDecimal();
|
value = prevState.toBigDecimal();
|
||||||
weight = BigDecimal.valueOf(
|
weight = BigDecimal.valueOf(Duration.between(prevInstant, nextInstant).toMillis());
|
||||||
Duration.between(prevItem.getTimestamp(), nextItem.getTimestamp()).toMillis());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevItem = nextItem;
|
prevItem = nextItem;
|
||||||
|
prevInstant = nextInstant;
|
||||||
break;
|
break;
|
||||||
case RIGHT:
|
case RIGHT:
|
||||||
nextState = getPersistedValue(nextItem, unit);
|
nextState = getPersistedValue(nextItem, unit);
|
||||||
if (nextState != null) {
|
if (nextState != null) {
|
||||||
value = nextState.toBigDecimal();
|
value = nextState.toBigDecimal();
|
||||||
if (prevItem == null) {
|
if (prevItem == null) {
|
||||||
weight = BigDecimal.valueOf(Duration.between(begin, nextItem.getTimestamp()).toMillis());
|
weight = BigDecimal.valueOf(Duration.between(begin, nextInstant).toMillis());
|
||||||
} else {
|
} else {
|
||||||
weight = BigDecimal.valueOf(
|
weight = BigDecimal.valueOf(Duration.between(prevInstant, nextInstant).toMillis());
|
||||||
Duration.between(prevItem.getTimestamp(), nextItem.getTimestamp()).toMillis());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevItem = nextItem;
|
prevItem = nextItem;
|
||||||
|
prevInstant = nextInstant;
|
||||||
break;
|
break;
|
||||||
case TRAPEZOIDAL:
|
case TRAPEZOIDAL:
|
||||||
if (prevItem != null) {
|
if (prevItem != null) {
|
||||||
@@ -2258,11 +2264,11 @@ public class PersistenceExtensions {
|
|||||||
if (prevState != null && nextState != null) {
|
if (prevState != null && nextState != null) {
|
||||||
value = prevState.toBigDecimal().add(nextState.toBigDecimal())
|
value = prevState.toBigDecimal().add(nextState.toBigDecimal())
|
||||||
.divide(BigDecimal.valueOf(2));
|
.divide(BigDecimal.valueOf(2));
|
||||||
weight = BigDecimal.valueOf(
|
weight = BigDecimal.valueOf(Duration.between(prevInstant, nextInstant).toMillis());
|
||||||
Duration.between(prevItem.getTimestamp(), nextItem.getTimestamp()).toMillis());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevItem = nextItem;
|
prevItem = nextItem;
|
||||||
|
prevInstant = nextInstant;
|
||||||
break;
|
break;
|
||||||
case MIDPOINT:
|
case MIDPOINT:
|
||||||
if (prevItem != null) {
|
if (prevItem != null) {
|
||||||
@@ -2272,12 +2278,12 @@ public class PersistenceExtensions {
|
|||||||
if (midpointStartBucket && !prevDuration.isZero() && prevState != null) {
|
if (midpointStartBucket && !prevDuration.isZero() && prevState != null) {
|
||||||
// Add half of the start bucket with the start value (left approximation)
|
// Add half of the start bucket with the start value (left approximation)
|
||||||
sum = sum.add(prevState.toBigDecimal()
|
sum = sum.add(prevState.toBigDecimal()
|
||||||
.multiply(BigDecimal.valueOf(prevDuration.dividedBy(2).toMillis())));
|
.multiply(BigDecimal.valueOf(prevDuration.toMillis() / 2)));
|
||||||
midpointStartBucket = false;
|
midpointStartBucket = false;
|
||||||
}
|
}
|
||||||
nextDuration = Duration.between(prevItem.getTimestamp(), nextItem.getTimestamp());
|
nextDuration = Duration.between(prevInstant, nextInstant);
|
||||||
weight = prevDuration.isZero() || nextDuration.isZero() ? BigDecimal.ZERO
|
weight = prevDuration.isZero() || nextDuration.isZero() ? BigDecimal.ZERO
|
||||||
: BigDecimal.valueOf(prevDuration.plus(nextDuration).dividedBy(2).toMillis());
|
: BigDecimal.valueOf(prevDuration.plus(nextDuration).toMillis() / 2);
|
||||||
if (!nextDuration.isZero()) {
|
if (!nextDuration.isZero()) {
|
||||||
prevDuration = nextDuration;
|
prevDuration = nextDuration;
|
||||||
}
|
}
|
||||||
@@ -2285,6 +2291,7 @@ public class PersistenceExtensions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevItem = nextItem;
|
prevItem = nextItem;
|
||||||
|
prevInstant = nextInstant;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sum = sum.add(value.multiply(weight));
|
sum = sum.add(value.multiply(weight));
|
||||||
@@ -2295,7 +2302,7 @@ public class PersistenceExtensions {
|
|||||||
DecimalType dtState = getPersistedValue(prevItem, unit);
|
DecimalType dtState = getPersistedValue(prevItem, unit);
|
||||||
if (dtState != null) {
|
if (dtState != null) {
|
||||||
BigDecimal value = dtState.toBigDecimal();
|
BigDecimal value = dtState.toBigDecimal();
|
||||||
BigDecimal weight = BigDecimal.valueOf(prevDuration.dividedBy(2).toMillis());
|
BigDecimal weight = BigDecimal.valueOf(prevDuration.toMillis() / 2);
|
||||||
sum = sum.add(value.multiply(weight));
|
sum = sum.add(value.multiply(weight));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user