[New][Backport] New methods on StrolchTimedState and ITimeVariable
This commit is contained in:
parent
d24352ed41
commit
cb343f4f4e
|
@ -89,6 +89,16 @@ public abstract class AbstractStrolchTimedState<T extends IValue> extends Abstra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInterpretationDefined() {
|
||||||
|
return !INTERPRETATION_NONE.equals(this.interpretation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInterpretationEmpty() {
|
||||||
|
return INTERPRETATION_NONE.equals(this.interpretation);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUom() {
|
public String getUom() {
|
||||||
return this.uom;
|
return this.uom;
|
||||||
|
@ -104,6 +114,16 @@ public abstract class AbstractStrolchTimedState<T extends IValue> extends Abstra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUomDefined() {
|
||||||
|
return !UOM_NONE.equals(this.uom);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUomEmpty() {
|
||||||
|
return UOM_NONE.equals(this.uom);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIndex(int index) {
|
public void setIndex(int index) {
|
||||||
assertNotReadonly();
|
assertNotReadonly();
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.model.timedstate;
|
package li.strolch.model.timedstate;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NavigableSet;
|
||||||
|
|
||||||
import li.strolch.model.Resource;
|
import li.strolch.model.Resource;
|
||||||
import li.strolch.model.StrolchElement;
|
import li.strolch.model.StrolchElement;
|
||||||
import li.strolch.model.StrolchModelConstants;
|
import li.strolch.model.StrolchModelConstants;
|
||||||
|
@ -66,6 +70,20 @@ public interface StrolchTimedState<T extends IValue> extends StrolchElement {
|
||||||
*/
|
*/
|
||||||
void setUom(String uom);
|
void setUom(String uom);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the UOM is not {@link StrolchModelConstants#UOM_NONE}
|
||||||
|
*
|
||||||
|
* @return true if the UOM is not {@link StrolchModelConstants#UOM_NONE}
|
||||||
|
*/
|
||||||
|
boolean isUomDefined();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the UOM is set to {@link StrolchModelConstants#UOM_NONE}
|
||||||
|
*
|
||||||
|
* @return true if the UOM is set to {@link StrolchModelConstants#UOM_NONE}
|
||||||
|
*/
|
||||||
|
boolean isUomEmpty();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the index of this {@link Parameter}. This can be used to sort the parameters in a UI
|
* Returns the index of this {@link Parameter}. This can be used to sort the parameters in a UI
|
||||||
*
|
*
|
||||||
|
@ -108,6 +126,20 @@ public interface StrolchTimedState<T extends IValue> extends StrolchElement {
|
||||||
*/
|
*/
|
||||||
void setInterpretation(String interpretation);
|
void setInterpretation(String interpretation);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the interpretation is not {@link StrolchModelConstants#INTERPRETATION_NONE}
|
||||||
|
*
|
||||||
|
* @return true if the interpretation is not {@link StrolchModelConstants#INTERPRETATION_NONE}
|
||||||
|
*/
|
||||||
|
boolean isInterpretationDefined();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the interpretation is set to {@link StrolchModelConstants#INTERPRETATION_NONE}
|
||||||
|
*
|
||||||
|
* @return true if the interpretation is set to {@link StrolchModelConstants#INTERPRETATION_NONE}
|
||||||
|
*/
|
||||||
|
boolean isInterpretationEmpty();
|
||||||
|
|
||||||
ITimeValue<T> getNextMatch(Long time, T value);
|
ITimeValue<T> getNextMatch(Long time, T value);
|
||||||
|
|
||||||
ITimeValue<T> getPreviousMatch(Long time, T value);
|
ITimeValue<T> getPreviousMatch(Long time, T value);
|
||||||
|
@ -134,4 +166,50 @@ public interface StrolchTimedState<T extends IValue> extends StrolchElement {
|
||||||
StrolchTimedState<T> getClone();
|
StrolchTimedState<T> getClone();
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trims this timed state, so it has at most the given number of values
|
||||||
|
*
|
||||||
|
* @param maxValues
|
||||||
|
* the number of values to keep
|
||||||
|
*
|
||||||
|
* @return true if the state was trimmed, false if not
|
||||||
|
*/
|
||||||
|
default boolean trim(int maxValues) {
|
||||||
|
assertNotReadonly();
|
||||||
|
|
||||||
|
ITimeVariable<T> timeEvolution = getTimeEvolution();
|
||||||
|
NavigableSet<? extends ITimeValue<?>> values = timeEvolution.getValues();
|
||||||
|
if (values.size() < maxValues)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Iterator<? extends ITimeValue<?>> iterator = values.descendingIterator();
|
||||||
|
ITimeValue<?> next = iterator.next();
|
||||||
|
for (int i = 0; i < maxValues - 1; i++) {
|
||||||
|
next = iterator.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return !timeEvolution.removePastValues(next.getTime()).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trims this timed state, so all values before the given time stamp
|
||||||
|
*
|
||||||
|
* @param timeStamp
|
||||||
|
* the max date the values may have
|
||||||
|
* @param keepLastValue
|
||||||
|
* if true, and the last value is before the max
|
||||||
|
*
|
||||||
|
* @return true if the state was trimmed, false if not
|
||||||
|
*/
|
||||||
|
default boolean trim(ZonedDateTime timeStamp, boolean keepLastValue) {
|
||||||
|
assertNotReadonly();
|
||||||
|
ITimeVariable<T> timeEvolution = getTimeEvolution();
|
||||||
|
|
||||||
|
long time = timeStamp.toInstant().toEpochMilli();
|
||||||
|
if (keepLastValue && timeEvolution.getFutureValues(time).isEmpty())
|
||||||
|
time = timeEvolution.getValueAt(time).getTime();
|
||||||
|
|
||||||
|
return !timeEvolution.removePastValues(time).isEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ public interface ITimeVariable<T extends IValue> {
|
||||||
* @param time
|
* @param time
|
||||||
* the time the sequence starts with
|
* the time the sequence starts with
|
||||||
*
|
*
|
||||||
* <b>Note:</b> The returned result is unmodifiable
|
* <b>Note:</b> The returned result is unmodifiable
|
||||||
*
|
*
|
||||||
* @return the sequence of {@link ITimeValue} objects in the future
|
* @return the sequence of {@link ITimeValue} objects in the future
|
||||||
*/
|
*/
|
||||||
|
@ -82,7 +82,7 @@ public interface ITimeVariable<T extends IValue> {
|
||||||
* @param time
|
* @param time
|
||||||
* the time the sequence starts with
|
* the time the sequence starts with
|
||||||
*
|
*
|
||||||
* <b>Note:</b> The returned result is unmodifiable
|
* <b>Note:</b> The returned result is unmodifiable
|
||||||
*
|
*
|
||||||
* @return the sequence of {@link ITimeValue} objects in the future
|
* @return the sequence of {@link ITimeValue} objects in the future
|
||||||
*/
|
*/
|
||||||
|
@ -144,4 +144,17 @@ public interface ITimeVariable<T extends IValue> {
|
||||||
* parent
|
* parent
|
||||||
*/
|
*/
|
||||||
void setReadonly();
|
void setReadonly();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of values stored on this time variable
|
||||||
|
*
|
||||||
|
* @return the number of values stored on this time variable
|
||||||
|
*/
|
||||||
|
int size();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given {@link ITimeVariable} is equal to this {@link ITimeVariable} by validating that the
|
||||||
|
* values {@link IValue IValues} have the same time and actual value
|
||||||
|
*/
|
||||||
|
boolean equals(ITimeVariable<T> other);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,7 @@ package li.strolch.model.timevalue.impl;
|
||||||
import static java.util.Collections.unmodifiableNavigableSet;
|
import static java.util.Collections.unmodifiableNavigableSet;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Iterator;
|
import java.util.*;
|
||||||
import java.util.NavigableSet;
|
|
||||||
import java.util.SortedSet;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import li.strolch.exception.StrolchModelException;
|
import li.strolch.exception.StrolchModelException;
|
||||||
|
@ -39,6 +36,11 @@ public class TimeVariable<T extends IValue> implements ITimeVariable<T>, Seriali
|
||||||
public NavigableSet<ITimeValue<T>> container = new TreeSet<>();
|
public NavigableSet<ITimeValue<T>> container = new TreeSet<>();
|
||||||
private boolean readonly;
|
private boolean readonly;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return this.container.size();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ITimeValue<T> getValueAt(long time) {
|
public ITimeValue<T> getValueAt(long time) {
|
||||||
return this.container.floor(new TimeValue<>(time, null));
|
return this.container.floor(new TimeValue<>(time, null));
|
||||||
|
@ -170,4 +172,36 @@ public class TimeVariable<T extends IValue> implements ITimeVariable<T>, Seriali
|
||||||
+ " is currently readOnly, to modify clone first!");
|
+ " is currently readOnly, to modify clone first!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(ITimeVariable<T> o) {
|
||||||
|
return equals((Object) o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
TimeVariable<T> other = (TimeVariable<T>) o;
|
||||||
|
if (this.container.size() != other.container.size())
|
||||||
|
return false;
|
||||||
|
Iterator<ITimeValue<T>> thisIter = this.container.iterator();
|
||||||
|
Iterator<ITimeValue<T>> thatIter = other.container.iterator();
|
||||||
|
while (thisIter.hasNext()) {
|
||||||
|
ITimeValue<T> thisNext = thisIter.next();
|
||||||
|
ITimeValue<T> thatNext = thatIter.next();
|
||||||
|
if (!thisNext.equals(thatNext))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(this.container);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,10 @@ package li.strolch.model.timedstate;
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static li.strolch.model.ModelGenerator.*;
|
import static li.strolch.model.ModelGenerator.*;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -129,6 +131,75 @@ public class StrolchTimedStateTest {
|
||||||
assertEquals(asSet(STATE_STRING_TIME_30), valueAt30.getValue().getValue());
|
assertEquals(asSet(STATE_STRING_TIME_30), valueAt30.getValue().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTrimTimedState1() {
|
||||||
|
|
||||||
|
Resource myRes = createResource("@1", "Test With States", "Stated");
|
||||||
|
FloatTimedState floatState = myRes.getTimedState(STATE_FLOAT_ID);
|
||||||
|
|
||||||
|
boolean trimmed = floatState.trim(20);
|
||||||
|
assertFalse(trimmed);
|
||||||
|
assertEquals(4, floatState.getTimeEvolution().getValues().size());
|
||||||
|
|
||||||
|
long now = ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(20).toInstant().toEpochMilli();
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
floatState.getTimeEvolution().setValueAt(now, new FloatValue(i));
|
||||||
|
now += 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(20, floatState.getTimeEvolution().getValues().size());
|
||||||
|
trimmed = floatState.trim(20);
|
||||||
|
assertFalse(trimmed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTrimTimedState2() {
|
||||||
|
|
||||||
|
Resource myRes = createResource("@1", "Test With States", "Stated");
|
||||||
|
FloatTimedState floatState = myRes.getTimedState(STATE_FLOAT_ID);
|
||||||
|
|
||||||
|
assertFalse(floatState.trim(20));
|
||||||
|
assertEquals(4, floatState.getTimeEvolution().getValues().size());
|
||||||
|
|
||||||
|
long now = ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(20).toInstant().toEpochMilli();
|
||||||
|
|
||||||
|
for (int i = 0; i < 50; i++) {
|
||||||
|
floatState.getTimeEvolution().setValueAt(now, new FloatValue(i));
|
||||||
|
now += 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(54, floatState.getTimeEvolution().getValues().size());
|
||||||
|
assertTrue(floatState.trim(20));
|
||||||
|
assertEquals(20, floatState.getTimeEvolution().getValues().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTrimTimedState3() {
|
||||||
|
ZonedDateTime now = ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(20);
|
||||||
|
|
||||||
|
Resource myRes = createResource("@1", "Test With States", "Stated");
|
||||||
|
FloatTimedState floatState = myRes.getTimedState(STATE_FLOAT_ID);
|
||||||
|
assertEquals(4, floatState.getTimeEvolution().getValues().size());
|
||||||
|
|
||||||
|
assertTrue(floatState.trim(now, true));
|
||||||
|
assertEquals(1, floatState.getTimeEvolution().getValues().size());
|
||||||
|
assertEquals(STATE_TIME_30, floatState.getTimeEvolution().getValues().iterator().next().getTime().longValue());
|
||||||
|
|
||||||
|
assertFalse(floatState.trim(now, true));
|
||||||
|
assertEquals(1, floatState.getTimeEvolution().getValues().size());
|
||||||
|
|
||||||
|
assertTrue(floatState.trim(now, false));
|
||||||
|
assertEquals(0, floatState.getTimeEvolution().getValues().size());
|
||||||
|
|
||||||
|
ZonedDateTime later = now.plusDays(1);
|
||||||
|
floatState.setStateFromStringAt(later.toInstant().toEpochMilli(), "55.0");
|
||||||
|
floatState.setStateFromStringAt(now.toInstant().toEpochMilli(), "56.0");
|
||||||
|
assertEquals(2, floatState.getTimeEvolution().getValues().size());
|
||||||
|
assertFalse(floatState.trim(now, true));
|
||||||
|
assertEquals(2, floatState.getTimeEvolution().getValues().size());
|
||||||
|
}
|
||||||
|
|
||||||
private static Set<AString> asSet(String value) {
|
private static Set<AString> asSet(String value) {
|
||||||
HashSet<AString> hashSet = new HashSet<>();
|
HashSet<AString> hashSet = new HashSet<>();
|
||||||
hashSet.add(new AString(value));
|
hashSet.add(new AString(value));
|
||||||
|
|
Loading…
Reference in New Issue