Skip to content

Commit c123341

Browse files
authored
[mapdb] Store and restore lastState, lastStateChange and lastChangeUpdate (openhab#17820)
* persist and restore previous state and last state change Signed-off-by: Mark Herwege <[email protected]>
1 parent 94313ba commit c123341

File tree

3 files changed

+67
-10
lines changed

3 files changed

+67
-10
lines changed

bundles/org.openhab.persistence.mapdb/src/main/java/org/openhab/persistence/mapdb/internal/MapDbItem.java

+25-9
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@
1313
package org.openhab.persistence.mapdb.internal;
1414

1515
import java.text.DateFormat;
16-
import java.time.Instant;
1716
import java.time.ZoneId;
1817
import java.time.ZonedDateTime;
1918
import java.util.Date;
2019

2120
import org.eclipse.jdt.annotation.NonNullByDefault;
2221
import org.eclipse.jdt.annotation.Nullable;
23-
import org.openhab.core.persistence.HistoricItem;
22+
import org.openhab.core.persistence.PersistedItem;
2423
import org.openhab.core.persistence.PersistenceItemInfo;
2524
import org.openhab.core.types.State;
2625
import org.openhab.core.types.UnDefType;
@@ -29,21 +28,24 @@
2928
* This is a Java bean used to persist item states with timestamps in the database.
3029
*
3130
* @author Jens Viebig - Initial contribution
31+
* @author Mark Herwege - Add lastState and lastStateChange
3232
*
3333
*/
3434
@NonNullByDefault
35-
public class MapDbItem implements HistoricItem, PersistenceItemInfo {
35+
class MapDbItem implements PersistedItem, PersistenceItemInfo {
3636

3737
private String name = "";
3838
private State state = UnDefType.NULL;
3939
private Date timestamp = new Date(0);
40+
private @Nullable State lastState = null;
41+
private @Nullable Date lastStateChange = null;
4042

4143
@Override
4244
public String getName() {
4345
return name;
4446
}
4547

46-
public void setName(String name) {
48+
void setName(String name) {
4749
this.name = name;
4850
}
4951

@@ -52,7 +54,7 @@ public State getState() {
5254
return state;
5355
}
5456

55-
public void setState(State state) {
57+
void setState(State state) {
5658
this.state = state;
5759
}
5860

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

64-
public void setTimestamp(Date timestamp) {
66+
void setTimestamp(Date timestamp) {
6567
this.timestamp = timestamp;
6668
}
6769

6870
@Override
69-
public Instant getInstant() {
70-
return timestamp.toInstant();
71+
public @Nullable State getLastState() {
72+
return lastState;
73+
}
74+
75+
void setLastState(@Nullable State lastState) {
76+
this.lastState = lastState;
77+
}
78+
79+
@Override
80+
public @Nullable ZonedDateTime getLastStateChange() {
81+
return lastStateChange != null ? ZonedDateTime.ofInstant(lastStateChange.toInstant(), ZoneId.systemDefault())
82+
: null;
83+
}
84+
85+
void setLastStateChange(@Nullable Date lastStateChange) {
86+
this.lastStateChange = lastStateChange;
7187
}
7288

7389
@Override
@@ -90,7 +106,7 @@ public String toString() {
90106
return null;
91107
}
92108

93-
public boolean isValid() {
109+
boolean isValid() {
94110
return name != null && state != null && timestamp != null;
95111
}
96112
}

bundles/org.openhab.persistence.mapdb/src/main/java/org/openhab/persistence/mapdb/internal/MapDbPersistenceService.java

+17-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.nio.file.Files;
1919
import java.nio.file.Path;
2020
import java.time.Instant;
21+
import java.time.ZonedDateTime;
2122
import java.util.Date;
2223
import java.util.List;
2324
import java.util.Locale;
@@ -38,6 +39,7 @@
3839
import org.openhab.core.library.types.DateTimeType;
3940
import org.openhab.core.persistence.FilterCriteria;
4041
import org.openhab.core.persistence.HistoricItem;
42+
import org.openhab.core.persistence.PersistedItem;
4143
import org.openhab.core.persistence.PersistenceItemInfo;
4244
import org.openhab.core.persistence.PersistenceService;
4345
import org.openhab.core.persistence.QueryablePersistenceService;
@@ -185,7 +187,11 @@ public void store(Item item, @Nullable String alias) {
185187
MapDbItem mItem = new MapDbItem();
186188
mItem.setName(localAlias);
187189
mItem.setState(state);
188-
mItem.setTimestamp(new Date());
190+
mItem.setLastState(item.getLastState());
191+
ZonedDateTime lastStateUpdate = item.getLastStateUpdate();
192+
mItem.setTimestamp(lastStateUpdate != null ? Date.from(lastStateUpdate.toInstant()) : new Date());
193+
ZonedDateTime lastStateChange = item.getLastStateChange();
194+
mItem.setLastStateChange(lastStateChange != null ? Date.from(lastStateChange.toInstant()) : null);
189195
threadPool.submit(() -> {
190196
String json = serialize(mItem);
191197
map.put(localAlias, json);
@@ -204,6 +210,16 @@ public Iterable<HistoricItem> query(FilterCriteria filter) {
204210
return item.isPresent() ? List.of(item.get()) : List.of();
205211
}
206212

213+
@Override
214+
public @Nullable PersistedItem persistedItem(String itemName) {
215+
String json = map.get(itemName);
216+
if (json == null) {
217+
return null;
218+
}
219+
Optional<MapDbItem> item = deserialize(json);
220+
return item.orElse(null);
221+
}
222+
207223
private String serialize(MapDbItem item) {
208224
return mapper.toJson(item);
209225
}

itests/org.openhab.persistence.mapdb.tests/src/main/java/org/openhab/persistence/mapdb/MapDbPersistenceServiceOSGiTest.java

+25
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
1818
import static org.hamcrest.collection.IsEmptyIterable.emptyIterable;
1919
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
20+
import static org.junit.jupiter.api.Assertions.assertNull;
2021

2122
import java.io.File;
2223
import java.io.IOException;
2324
import java.nio.file.Files;
2425
import java.nio.file.Path;
2526
import java.nio.file.Paths;
27+
import java.time.ZonedDateTime;
2628
import java.util.stream.Stream;
2729

2830
import org.junit.jupiter.api.AfterAll;
@@ -32,6 +34,7 @@
3234
import org.openhab.core.library.items.ColorItem;
3335
import org.openhab.core.library.items.DimmerItem;
3436
import org.openhab.core.library.items.SwitchItem;
37+
import org.openhab.core.library.types.DecimalType;
3538
import org.openhab.core.library.types.HSBType;
3639
import org.openhab.core.library.types.OnOffType;
3740
import org.openhab.core.library.types.PercentType;
@@ -133,4 +136,26 @@ public void queryShouldFindStoredItemsByAlias() {
133136
waitForAssert(() -> assertThat(persistenceService.query(filterByAlias),
134137
contains(allOf(hasProperty("name", equalTo(alias)), hasProperty("state", equalTo(state))))));
135138
}
139+
140+
@Test
141+
public void persistedItemShouldFindItem() {
142+
String name = "decimal";
143+
State state = DecimalType.valueOf("100");
144+
State lastState = DecimalType.ZERO;
145+
ZonedDateTime lastStateUpdate = ZonedDateTime.now().minusHours(1);
146+
ZonedDateTime lastStateChange = ZonedDateTime.now().minusHours(2);
147+
148+
GenericItem item = new DimmerItem(name);
149+
item.setState(state, lastState, lastStateUpdate, lastStateChange);
150+
151+
assertNull(persistenceService.persistedItem(name));
152+
153+
persistenceService.store(item);
154+
155+
waitForAssert(() -> assertThat(persistenceService.persistedItem(name),
156+
allOf(hasProperty("name", equalTo(name)), hasProperty("state", equalTo(state)),
157+
hasProperty("lastState", equalTo(lastState)),
158+
hasProperty("timestamp", any(ZonedDateTime.class)),
159+
hasProperty("lastStateChange", any(ZonedDateTime.class)))));
160+
}
136161
}

0 commit comments

Comments
 (0)