Skip to content

Commit

Permalink
Add getLastChange, getLastUpdate, and getPreviousState to Gener…
Browse files Browse the repository at this point in the history
…icItem

Signed-off-by: Jimmy Tanagra <[email protected]>
  • Loading branch information
jimtng committed Aug 17, 2024
1 parent 7659783 commit 0c7eeed
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package org.openhab.core.items;

import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -77,6 +78,10 @@ public abstract class GenericItem implements ActiveItem {
protected final String type;

protected State state = UnDefType.NULL;
protected @Nullable State previousState;

protected @Nullable ZonedDateTime lastUpdate;
protected @Nullable ZonedDateTime lastChange;

protected @Nullable String label;

Expand All @@ -103,6 +108,33 @@ public State getState() {
return state.as(typeClass);
}

/**
* Returns the previous state of the item.
*
* @return the previous state of the item, or null if the item has never been changed.
*/
public @Nullable State getPreviousState() {
return previousState;
}

/**
* Returns the time the item was last updated.
*
* @return the time the item was last updated, or null if the item has never been updated.
*/
public @Nullable ZonedDateTime getLastUpdate() {
return lastUpdate;
}

/**
* Returns the time the item was last changed.
*
* @return the time the item was last changed, or null if the item has never been changed.
*/
public @Nullable ZonedDateTime getLastChange() {
return lastChange;
}

@Override
public String getUID() {
return getName();
Expand Down Expand Up @@ -218,13 +250,20 @@ public void setState(State state) {
* @param state new state of this item
*/
protected final void applyState(State state) {
ZonedDateTime now = ZonedDateTime.now();
State oldState = this.state;
boolean stateChanged = !oldState.equals(state);
this.state = state;
if (stateChanged) {
previousState = oldState; // update before we notify listeners
}
notifyListeners(oldState, state);
sendStateUpdatedEvent(state);
if (!oldState.equals(state)) {
if (stateChanged) {
sendStateChangedEvent(state, oldState);
lastChange = now; // update after we've notified listeners
}
lastUpdate = now;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
package org.openhab.core.items;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.closeTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

import java.time.ZonedDateTime;
import java.util.List;
import java.util.Locale;

Expand All @@ -39,6 +42,7 @@
import org.openhab.core.types.State;
import org.openhab.core.types.StateDescriptionFragmentBuilder;
import org.openhab.core.types.StateOption;
import org.openhab.core.types.UnDefType;

/**
* The GenericItemTest tests functionality of the GenericItem.
Expand Down Expand Up @@ -133,6 +137,47 @@ public void testGetStateAsWithNull() {
assertNull(item.getStateAs(toNull()));
}

@Test
public void testGetLastUpdate() {
TestItem item = new TestItem("member1");
assertNull(item.getLastUpdate());
item.setState(PercentType.HUNDRED);
assertThat(item.getLastUpdate().toInstant().toEpochMilli() * 1.0,
is(closeTo(ZonedDateTime.now().toInstant().toEpochMilli(), 5)));
}

@Test
public void testGetLastChange() throws InterruptedException {
TestItem item = new TestItem("member1");
assertNull(item.getLastChange());
item.setState(PercentType.HUNDRED);
ZonedDateTime initialChangeTime = ZonedDateTime.now();
assertThat(item.getLastChange().toInstant().toEpochMilli() * 1.0,
is(closeTo(initialChangeTime.toInstant().toEpochMilli(), 5)));

Thread.sleep(50);
item.setState(PercentType.HUNDRED);
assertThat(item.getLastChange().toInstant().toEpochMilli() * 1.0,
is(closeTo(initialChangeTime.toInstant().toEpochMilli(), 5)));

Thread.sleep(50);
ZonedDateTime secondChangeTime = ZonedDateTime.now();
item.setState(PercentType.ZERO);
assertThat(item.getLastChange().toInstant().toEpochMilli() * 1.0,
is(closeTo(secondChangeTime.toInstant().toEpochMilli(), 5)));
}

@Test
public void testGetPreviousState() {
TestItem item = new TestItem("member1");
assertEquals(UnDefType.NULL, item.getState());
assertNull(item.getPreviousState());
item.setState(PercentType.HUNDRED);
assertEquals(UnDefType.NULL, item.getPreviousState());
item.setState(PercentType.ZERO);
assertEquals(PercentType.HUNDRED, item.getPreviousState());
}

@Test
public void testDispose() {
TestItem item = new TestItem("test");
Expand Down

0 comments on commit 0c7eeed

Please sign in to comment.