Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mapdb] Store and restore lastState, lastStateChange and lastChangeUpdate #17820

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
package org.openhab.persistence.mapdb.internal;

import java.text.DateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.persistence.HistoricItem;
import org.openhab.core.persistence.PersistedItem;
import org.openhab.core.persistence.PersistenceItemInfo;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
Expand All @@ -29,21 +28,24 @@
* This is a Java bean used to persist item states with timestamps in the database.
*
* @author Jens Viebig - Initial contribution
* @author Mark Herwege - Add lastState and lastStateChange
*
*/
@NonNullByDefault
public class MapDbItem implements HistoricItem, PersistenceItemInfo {
class MapDbItem implements PersistedItem, PersistenceItemInfo {

private String name = "";
private State state = UnDefType.NULL;
private Date timestamp = new Date(0);
private @Nullable State lastState = null;
private @Nullable Date lastStateChange = null;

@Override
public String getName() {
return name;
}

public void setName(String name) {
void setName(String name) {
this.name = name;
}

Expand All @@ -52,7 +54,7 @@ public State getState() {
return state;
}

public void setState(State state) {
void setState(State state) {
this.state = state;
}

Expand All @@ -61,13 +63,27 @@ public ZonedDateTime getTimestamp() {
return ZonedDateTime.ofInstant(timestamp.toInstant(), ZoneId.systemDefault());
}

public void setTimestamp(Date timestamp) {
void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}

@Override
public Instant getInstant() {
return timestamp.toInstant();
public @Nullable State getLastState() {
return lastState;
}

void setLastState(@Nullable State lastState) {
this.lastState = lastState;
}

@Override
public @Nullable ZonedDateTime getLastStateChange() {
return lastStateChange != null ? ZonedDateTime.ofInstant(lastStateChange.toInstant(), ZoneId.systemDefault())
: null;
}

void setLastStateChange(@Nullable Date lastStateChange) {
this.lastStateChange = lastStateChange;
}

@Override
Expand All @@ -90,7 +106,7 @@ public String toString() {
return null;
}

public boolean isValid() {
boolean isValid() {
return name != null && state != null && timestamp != null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
import java.util.Locale;
Expand All @@ -35,6 +36,7 @@
import org.openhab.core.OpenHAB;
import org.openhab.core.common.ThreadPoolManager;
import org.openhab.core.items.Item;
import org.openhab.core.items.ManagedItemProvider.PersistedItem;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.persistence.FilterCriteria;
import org.openhab.core.persistence.HistoricItem;
Expand Down Expand Up @@ -163,7 +165,7 @@ public String getLabel(@Nullable Locale locale) {
@Override
public Set<PersistenceItemInfo> getItemInfo() {
return map.values().stream().map(this::deserialize).flatMap(MapDbPersistenceService::streamOptional)
.collect(Collectors.<PersistenceItemInfo> toUnmodifiableSet());
.collect(Collectors.<PersistenceItemInfo>toUnmodifiableSet());
}

@Override
Expand All @@ -185,7 +187,11 @@ public void store(Item item, @Nullable String alias) {
MapDbItem mItem = new MapDbItem();
mItem.setName(localAlias);
mItem.setState(state);
mItem.setTimestamp(new Date());
mItem.setLastState(item.getLastState());
ZonedDateTime lastStateUpdate = item.getLastStateUpdate();
mItem.setTimestamp(lastStateUpdate != null ? Date.from(lastStateUpdate.toInstant()) : new Date());
ZonedDateTime lastStateChange = item.getLastStateChange();
mItem.setLastStateChange(lastStateChange != null ? Date.from(lastStateChange.toInstant()) : null);
threadPool.submit(() -> {
String json = serialize(mItem);
map.put(localAlias, json);
Expand All @@ -204,6 +210,16 @@ public Iterable<HistoricItem> query(FilterCriteria filter) {
return item.isPresent() ? List.of(item.get()) : List.of();
}

@Override
public @Nullable PersistedItem persistedItem(String itemName) {
String json = map.get(itemName);
if (json == null) {
return null;
}
Optional<MapDbItem> item = deserialize(json);
return item.orElse(null);
}

private String serialize(MapDbItem item) {
return mapper.toJson(item);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
import static org.hamcrest.collection.IsEmptyIterable.emptyIterable;
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
import static org.junit.jupiter.api.Assertions.assertNull;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.ZonedDateTime;
import java.util.stream.Stream;

import org.junit.jupiter.api.AfterAll;
Expand All @@ -32,6 +34,7 @@
import org.openhab.core.library.items.ColorItem;
import org.openhab.core.library.items.DimmerItem;
import org.openhab.core.library.items.SwitchItem;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.PercentType;
Expand Down Expand Up @@ -133,4 +136,26 @@ public void queryShouldFindStoredItemsByAlias() {
waitForAssert(() -> assertThat(persistenceService.query(filterByAlias),
contains(allOf(hasProperty("name", equalTo(alias)), hasProperty("state", equalTo(state))))));
}

@Test
public void persistedItemShouldFindItem() {
String name = "decimal";
State state = DecimalType.valueOf("100");
State lastState = DecimalType.ZERO;
ZonedDateTime lastStateUpdate = ZonedDateTime.now().minusHours(1);
ZonedDateTime lastStateChange = ZonedDateTime.now().minusHours(2);

GenericItem item = new DimmerItem(name);
item.setState(state, lastState, lastStateUpdate, lastStateChange);

assertNull(persistenceService.persistedItem(name));

persistenceService.store(item);

waitForAssert(() -> assertThat(persistenceService.persistedItem(name),
allOf(hasProperty("name", equalTo(name)), hasProperty("state", equalTo(state)),
hasProperty("lastState", equalTo(lastState)),
hasProperty("timestamp", any(ZonedDateTime.class)),
hasProperty("lastStateChange", any(ZonedDateTime.class)))));
}
}
Loading