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 034993e4fb..4d43fd92b3 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 @@ -1150,6 +1150,76 @@ public class PersistenceExtensions { } } + /** + * Gets the number of changes in historic data points of a given {@link Item} from a point in time until now. + * The default {@link PersistenceService} is used. + * + * @param item the {@link Item} to query + * @param begin the beginning point in time + * @return the number of state changes for this item + */ + public static long countStateChangesSince(Item item, ZonedDateTime begin) { + return countStateChangesSince(item, begin, getDefaultServiceId()); + } + + /** + * Gets the number of changes in historic data points of a given {@link Item} from a point in time until now. + * The {@link PersistenceService} identified by the serviceId is used. + * + * @param item the {@link Item} to query + * @param begin the beginning point in time + * @param serviceId the name of the {@link PersistenceService} to use + * @return the number of state changes for this item + */ + public static long countStateChangesSince(Item item, ZonedDateTime begin, String serviceId) { + return countStateChangesBetween(item, begin, null, serviceId); + } + + /** + * Gets the number of changes in historic data points of a given {@link Item} between two points in time. + * The default {@link PersistenceService} is used. + * + * @param item the {@link Item} to query + * @param begin the beginning point in time + * @param end the end point in time + * @return the number of state changes for this item + */ + public static long countStateChangesBetween(Item item, ZonedDateTime begin, @Nullable ZonedDateTime end) { + return countStateChangesBetween(item, begin, end, getDefaultServiceId()); + } + + /** + * Gets the number of changes in historic data points of a given {@link Item} between two points in time. + * The {@link PersistenceService} identified by the serviceId is used. + * + * @param item the {@link Item} to query + * @param begin the beginning point in time + * @param end the end point in time + * @param serviceId the name of the {@link PersistenceService} to use + * @return the number of state changes for this item + */ + public static long countStateChangesBetween(Item item, ZonedDateTime begin, @Nullable ZonedDateTime end, + String serviceId) { + Iterable result = getAllStatesBetween(item, begin, end, serviceId); + Iterator it = result.iterator(); + + if (!it.hasNext()) { + return 0; + } + + long count = 0; + State previousState = it.next().getState(); + while (it.hasNext()) { + HistoricItem historicItem = it.next(); + State state = historicItem.getState(); + if (!state.equals(previousState)) { + previousState = state; + count++; + } + } + return count; + } + private static @Nullable PersistenceService getService(String serviceId) { PersistenceService service = null; if (registry != null) { 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 b983db6ad3..698c0cc5ad 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 @@ -951,4 +951,41 @@ public class PersistenceExtensionsTest { ZonedDateTime.of(2000, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault())); assertEquals(0, counts); } + + @Test + public void testCountStateChangesSince() { + long counts = PersistenceExtensions.countStateChangesSince(numberItem, + ZonedDateTime.of(1980, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID); + assertEquals(32, counts); + + counts = PersistenceExtensions.countStateChangesSince(numberItem, + ZonedDateTime.of(2007, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID); + assertEquals(5, counts); + + counts = PersistenceExtensions.countStateChangesSince(numberItem, + ZonedDateTime.of(2020, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID); + assertEquals(0, counts); + + counts = PersistenceExtensions.countStateChangesSince(numberItem, + ZonedDateTime.of(2000, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault())); + assertEquals(0, counts); + } + + @Test + public void testCountStateChangesBetween() { + long counts = PersistenceExtensions.countStateChangesBetween(numberItem, + ZonedDateTime.of(1940, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), + ZonedDateTime.of(1970, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID); + assertEquals(0, counts); + + counts = PersistenceExtensions.countStateChangesBetween(numberItem, + ZonedDateTime.of(2005, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), + ZonedDateTime.of(2011, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), TestPersistenceService.ID); + assertEquals(6, counts); + + counts = PersistenceExtensions.countStateChangesBetween(numberItem, + ZonedDateTime.of(2005, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()), + ZonedDateTime.of(2011, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault())); + assertEquals(0, counts); + } }