diff --git a/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/ModifiablePersistenceService.java b/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/ModifiablePersistenceService.java index 2feb4f4660f..0d710c8cae4 100644 --- a/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/ModifiablePersistenceService.java +++ b/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/ModifiablePersistenceService.java @@ -46,6 +46,7 @@ public interface ModifiablePersistenceService extends QueryablePersistenceServic */ void store(Item item, ZonedDateTime date, State state); + // TODO: add a method for storing with alias to be in line with the ordinary store methods? /** * Removes data associated with an item from a persistence service. * If all data is removed for the specified item, the persistence service should free any resources associated with diff --git a/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/internal/PersistenceManager.java b/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/internal/PersistenceManager.java index 69b7fae7c66..fa4eb01eee5 100644 --- a/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/internal/PersistenceManager.java +++ b/bundles/org.openhab.core.persistence/src/main/java/org/openhab/core/persistence/internal/PersistenceManager.java @@ -12,6 +12,7 @@ */ package org.openhab.core.persistence.internal; +import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Collection; import java.util.HashSet; @@ -38,8 +39,10 @@ import org.openhab.core.items.ItemRegistry; import org.openhab.core.items.ItemRegistryChangeListener; import org.openhab.core.items.StateChangeListener; +import org.openhab.core.items.TimeSeriesListener; import org.openhab.core.persistence.FilterCriteria; import org.openhab.core.persistence.HistoricItem; +import org.openhab.core.persistence.ModifiablePersistenceService; import org.openhab.core.persistence.PersistenceItemConfiguration; import org.openhab.core.persistence.PersistenceService; import org.openhab.core.persistence.QueryablePersistenceService; @@ -60,6 +63,7 @@ import org.openhab.core.service.ReadyService.ReadyTracker; import org.openhab.core.service.StartLevelService; import org.openhab.core.types.State; +import org.openhab.core.types.TimeSeries; import org.openhab.core.types.UnDefType; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; @@ -80,7 +84,7 @@ @Component(immediate = true) @NonNullByDefault public class PersistenceManager implements ItemRegistryChangeListener, StateChangeListener, ReadyTracker, - PersistenceServiceConfigurationRegistryChangeListener { + PersistenceServiceConfigurationRegistryChangeListener, TimeSeriesListener { private final Logger logger = LoggerFactory.getLogger(PersistenceManager.class); @@ -300,6 +304,7 @@ public void added(Item item) { restoreItemStateIfNeeded(item); if (item instanceof GenericItem genericItem) { genericItem.addStateChangeListener(this); + genericItem.addTimeSeriesListener(this); } } @@ -307,6 +312,7 @@ public void added(Item item) { public void removed(Item item) { if (item instanceof GenericItem genericItem) { genericItem.removeStateChangeListener(this); + genericItem.removeTimeSeriesListener(this); } } @@ -326,6 +332,20 @@ public void stateUpdated(Item item, State state) { handleStateEvent(item, false); } + @Override + public void timeSeriesUpdated(Item item, TimeSeries timeSeries) { + persistenceServiceContainers.values().stream() + .filter(psc -> psc.persistenceService instanceof ModifiablePersistenceService) + // TODO: shall we add a different strategy for that or re-use update? a new strategy would be easier for + // applying future values + .forEach(container -> container.getMatchingConfigurations(PersistenceStrategy.Globals.UPDATE) + .filter(itemConfig -> appliesToItem(itemConfig, item)) + // TODO: shall we apply filters? If so, how should that look like? + .forEach(itemConfig -> timeSeries.getStates() + .forEach(e -> ((ModifiablePersistenceService) container.getPersistenceService()) + .store(item, e.timestamp().atZone(ZoneId.systemDefault()), e.state())))); + } + @Override public void onReadyMarkerAdded(ReadyMarker readyMarker) { ExecutorService scheduler = Executors.newSingleThreadExecutor(new NamedThreadFactory("persistenceManager")); diff --git a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/internal/CommunicationManager.java b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/internal/CommunicationManager.java index 51d1abee633..08d36dca881 100644 --- a/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/internal/CommunicationManager.java +++ b/bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/internal/CommunicationManager.java @@ -516,6 +516,7 @@ public void postCommand(ChannelUID channelUID, Command command) { public void sendTimeSeries(ChannelUID channelUID, TimeSeries timeSeries) { final Thing thing = getThing(channelUID.getThingUID()); handleCallFromHandler(channelUID, thing, profile -> { + // TODO: check which profiles need enhancements if (profile instanceof TimeSeriesProfile timeSeriesProfile) { timeSeriesProfile.onTimeSeriesFromHandler(timeSeries); } else { diff --git a/bundles/org.openhab.core/src/main/java/org/openhab/core/items/GenericItem.java b/bundles/org.openhab.core/src/main/java/org/openhab/core/items/GenericItem.java index b17c457c711..c97ef1c78d7 100644 --- a/bundles/org.openhab.core/src/main/java/org/openhab/core/items/GenericItem.java +++ b/bundles/org.openhab.core/src/main/java/org/openhab/core/items/GenericItem.java @@ -241,6 +241,7 @@ protected final void applyState(State state) { * * @param timeSeries new time series of this item */ + // TODO: implement overrides in sub-classes, waiting for UoM PR to be merged public void setTimeSeries(TimeSeries timeSeries) { applyTimeSeries(timeSeries); }