mirror of
https://github.com/danieldemus/openhab-core.git
synced 2026-07-29 12:34:22 +02:00
Add getLastStateChange, getLastStateUpdate, and getLastState to GenericItem (#4351)
* Add `getLastChange`, `getLastUpdate`, and `getPreviousState` to GenericItem * Rename to getLastStateChange, getLastStateUpdate, getLastState Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
This commit is contained in:
+5
-3
@@ -24,9 +24,11 @@ import org.openhab.core.types.StateDescription;
|
||||
*/
|
||||
public class EnrichedGroupItemDTO extends EnrichedItemDTO {
|
||||
|
||||
public EnrichedGroupItemDTO(ItemDTO itemDTO, EnrichedItemDTO[] members, String link, String state,
|
||||
String transformedState, StateDescription stateDescription, String unitSymbol) {
|
||||
super(itemDTO, link, state, transformedState, stateDescription, null, unitSymbol);
|
||||
public EnrichedGroupItemDTO(ItemDTO itemDTO, EnrichedItemDTO[] members, String link, String state, String lastState,
|
||||
Long lastStateUpdate, Long lastStateChange, String transformedState, StateDescription stateDescription,
|
||||
String unitSymbol) {
|
||||
super(itemDTO, link, state, lastState, lastStateUpdate, lastStateChange, transformedState, stateDescription,
|
||||
null, unitSymbol);
|
||||
this.members = members;
|
||||
this.groupType = ((GroupItemDTO) itemDTO).groupType;
|
||||
this.function = ((GroupItemDTO) itemDTO).function;
|
||||
|
||||
+10
-3
@@ -32,13 +32,17 @@ public class EnrichedItemDTO extends ItemDTO {
|
||||
public String state;
|
||||
public String transformedState;
|
||||
public StateDescription stateDescription;
|
||||
public String unitSymbol;
|
||||
public CommandDescription commandDescription;
|
||||
public String lastState;
|
||||
public Long lastStateUpdate;
|
||||
public Long lastStateChange;
|
||||
public String unitSymbol;
|
||||
public Map<String, Object> metadata;
|
||||
public Boolean editable;
|
||||
|
||||
public EnrichedItemDTO(ItemDTO itemDTO, String link, String state, String transformedState,
|
||||
StateDescription stateDescription, CommandDescription commandDescription, String unitSymbol) {
|
||||
public EnrichedItemDTO(ItemDTO itemDTO, String link, String state, String lastState, Long lastStateUpdate,
|
||||
Long lastStateChange, String transformedState, StateDescription stateDescription,
|
||||
CommandDescription commandDescription, String unitSymbol) {
|
||||
this.type = itemDTO.type;
|
||||
this.name = itemDTO.name;
|
||||
this.label = itemDTO.label;
|
||||
@@ -50,6 +54,9 @@ public class EnrichedItemDTO extends ItemDTO {
|
||||
this.transformedState = transformedState;
|
||||
this.stateDescription = stateDescription;
|
||||
this.commandDescription = commandDescription;
|
||||
this.lastState = lastState;
|
||||
this.lastStateUpdate = lastStateUpdate;
|
||||
this.lastStateChange = lastStateChange;
|
||||
this.unitSymbol = unitSymbol;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-4
@@ -18,6 +18,7 @@ import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -105,6 +106,12 @@ public class EnrichedItemDTOMapper {
|
||||
}
|
||||
StateDescription stateDescription = considerTransformation(item.getStateDescription(locale));
|
||||
|
||||
String lastState = Optional.ofNullable(item.getLastState()).map(State::toFullString).orElse(null);
|
||||
Long lastStateUpdate = Optional.ofNullable(item.getLastStateUpdate()).map(zdt -> zdt.toInstant().toEpochMilli())
|
||||
.orElse(null);
|
||||
Long lastStateChange = Optional.ofNullable(item.getLastStateChange()).map(zdt -> zdt.toInstant().toEpochMilli())
|
||||
.orElse(null);
|
||||
|
||||
final String link;
|
||||
if (uriBuilder != null) {
|
||||
link = uriBuilder.build(itemDTO.name).toASCIIString();
|
||||
@@ -139,11 +146,11 @@ public class EnrichedItemDTOMapper {
|
||||
} else {
|
||||
memberDTOs = new EnrichedItemDTO[0];
|
||||
}
|
||||
enrichedItemDTO = new EnrichedGroupItemDTO(itemDTO, memberDTOs, link, state, transformedState,
|
||||
stateDescription, unitSymbol);
|
||||
enrichedItemDTO = new EnrichedGroupItemDTO(itemDTO, memberDTOs, link, state, lastState, lastStateUpdate,
|
||||
lastStateChange, transformedState, stateDescription, unitSymbol);
|
||||
} else {
|
||||
enrichedItemDTO = new EnrichedItemDTO(itemDTO, link, state, transformedState, stateDescription,
|
||||
item.getCommandDescription(locale), unitSymbol);
|
||||
enrichedItemDTO = new EnrichedItemDTO(itemDTO, link, state, lastState, lastStateUpdate, lastStateChange,
|
||||
transformedState, stateDescription, item.getCommandDescription(locale), unitSymbol);
|
||||
}
|
||||
|
||||
return enrichedItemDTO;
|
||||
|
||||
@@ -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;
|
||||
@@ -77,6 +78,10 @@ public abstract class GenericItem implements ActiveItem {
|
||||
protected final String type;
|
||||
|
||||
protected State state = UnDefType.NULL;
|
||||
protected @Nullable State lastState;
|
||||
|
||||
protected @Nullable ZonedDateTime lastStateUpdate;
|
||||
protected @Nullable ZonedDateTime lastStateChange;
|
||||
|
||||
protected @Nullable String label;
|
||||
|
||||
@@ -103,6 +108,21 @@ public abstract class GenericItem implements ActiveItem {
|
||||
return state.as(typeClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable State getLastState() {
|
||||
return lastState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ZonedDateTime getLastStateUpdate() {
|
||||
return lastStateUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ZonedDateTime getLastStateChange() {
|
||||
return lastStateChange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUID() {
|
||||
return getName();
|
||||
@@ -218,13 +238,20 @@ public abstract class GenericItem implements ActiveItem {
|
||||
* @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) {
|
||||
lastState = oldState; // update before we notify listeners
|
||||
}
|
||||
notifyListeners(oldState, state);
|
||||
sendStateUpdatedEvent(state);
|
||||
if (!oldState.equals(state)) {
|
||||
if (stateChanged) {
|
||||
sendStateChangedEvent(state, oldState);
|
||||
lastStateChange = now; // update after we've notified listeners
|
||||
}
|
||||
lastStateUpdate = now;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
package org.openhab.core.items;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
@@ -51,6 +52,30 @@ public interface Item extends Identifiable<String> {
|
||||
*/
|
||||
<T extends State> @Nullable T getStateAs(Class<T> typeClass);
|
||||
|
||||
/**
|
||||
* Returns the previous state of the item.
|
||||
*
|
||||
* @return the previous state of the item, or null if the item has never been changed.
|
||||
*/
|
||||
@Nullable
|
||||
State getLastState();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Nullable
|
||||
ZonedDateTime getLastStateUpdate();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Nullable
|
||||
ZonedDateTime getLastStateChange();
|
||||
|
||||
/**
|
||||
* returns the name of the item
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -39,6 +42,7 @@ import org.openhab.core.types.CommandOption;
|
||||
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.
|
||||
@@ -133,6 +137,47 @@ public class GenericItemTest {
|
||||
assertNull(item.getStateAs(toNull()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastStateUpdate() {
|
||||
TestItem item = new TestItem("member1");
|
||||
assertNull(item.getLastStateUpdate());
|
||||
item.setState(PercentType.HUNDRED);
|
||||
assertThat(item.getLastStateUpdate().toInstant().toEpochMilli() * 1.0,
|
||||
is(closeTo(ZonedDateTime.now().toInstant().toEpochMilli(), 5)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastStateChange() throws InterruptedException {
|
||||
TestItem item = new TestItem("member1");
|
||||
assertNull(item.getLastStateChange());
|
||||
item.setState(PercentType.HUNDRED);
|
||||
ZonedDateTime initialChangeTime = ZonedDateTime.now();
|
||||
assertThat(item.getLastStateChange().toInstant().toEpochMilli() * 1.0,
|
||||
is(closeTo(initialChangeTime.toInstant().toEpochMilli(), 5)));
|
||||
|
||||
Thread.sleep(50);
|
||||
item.setState(PercentType.HUNDRED);
|
||||
assertThat(item.getLastStateChange().toInstant().toEpochMilli() * 1.0,
|
||||
is(closeTo(initialChangeTime.toInstant().toEpochMilli(), 5)));
|
||||
|
||||
Thread.sleep(50);
|
||||
ZonedDateTime secondChangeTime = ZonedDateTime.now();
|
||||
item.setState(PercentType.ZERO);
|
||||
assertThat(item.getLastStateChange().toInstant().toEpochMilli() * 1.0,
|
||||
is(closeTo(secondChangeTime.toInstant().toEpochMilli(), 5)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastState() {
|
||||
TestItem item = new TestItem("member1");
|
||||
assertEquals(UnDefType.NULL, item.getState());
|
||||
assertNull(item.getLastState());
|
||||
item.setState(PercentType.HUNDRED);
|
||||
assertEquals(UnDefType.NULL, item.getLastState());
|
||||
item.setState(PercentType.ZERO);
|
||||
assertEquals(PercentType.HUNDRED, item.getLastState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispose() {
|
||||
TestItem item = new TestItem("test");
|
||||
|
||||
Reference in New Issue
Block a user