diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/TsRollingArgumentEntry.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/TsRollingArgumentEntry.java index 90068d6b6f..bb559a3eec 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/TsRollingArgumentEntry.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/TsRollingArgumentEntry.java @@ -25,7 +25,6 @@ import org.thingsboard.script.api.tbel.TbelCfTsDoubleVal; import org.thingsboard.script.api.tbel.TbelCfTsRollingArg; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; -import org.thingsboard.server.exception.CalculatedFieldStateException; import java.util.ArrayList; import java.util.List; @@ -116,10 +115,11 @@ public class TsRollingArgumentEntry implements ArgumentEntry { case STRING -> value.getStrValue().ifPresent(aString -> tsRecords.put(ts, Double.parseDouble(aString))); case JSON -> value.getJsonValue().ifPresent(aString -> tsRecords.put(ts, Double.parseDouble(aString))); } - cleanupExpiredRecords(); } catch (Exception e) { tsRecords.put(ts, Double.NaN); log.debug("Invalid value '{}' for time series rolling arguments. Only numeric values are supported.", value.getValue()); + } finally { + cleanupExpiredRecords(); } } diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbelCfTsRollingArg.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbelCfTsRollingArg.java index ceae4e60c5..1bae5399cc 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbelCfTsRollingArg.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbelCfTsRollingArg.java @@ -61,14 +61,18 @@ public class TbelCfTsRollingArg implements TbelCfArg, Iterable val) { @@ -97,21 +105,28 @@ public class TbelCfTsRollingArg implements TbelCfArg, Iterable sortedValues = new ArrayList<>(); for (TbelCfTsDoubleVal value : values) { double val = value.getValue(); if (Double.isNaN(val)) { - return Double.NaN; + if (!ignoreNaN) { + return Double.NaN; + } + } else { + sortedValues.add(val); } - sortedValues.add(val); } Collections.sort(sortedValues); @@ -147,51 +172,90 @@ public class TbelCfTsRollingArg implements TbelCfArg, Iterable= 0; i--) { + double prevValue = values.get(i).getValue(); + if (!Double.isNaN(prevValue)) { + return prevValue; + } + } + throw new IllegalArgumentException("Rolling argument values are empty."); } public double first() { + return first(true); + } + + public double first(boolean ignoreNaN) { if (values.isEmpty()) { - return 0; + throw new IllegalArgumentException("Rolling argument values are empty."); } - return hasNaN() ? Double.NaN : values.get(0).getValue(); + double firstValue = values.get(0).getValue(); + if (!Double.isNaN(firstValue) || !ignoreNaN) { + return firstValue; + } + for (int i = 1; i < values.size(); i++) { + double nextValue = values.get(i).getValue(); + if (!Double.isNaN(nextValue)) { + return nextValue; + } + } + throw new IllegalArgumentException("Rolling argument values are empty."); } public double sum() { + return sum(true); + } + + public double sum(boolean ignoreNaN) { if (values.isEmpty()) { - return 0; + throw new IllegalArgumentException("Rolling argument values are empty."); } double sum = 0; for (TbelCfTsDoubleVal value : values) { double val = value.getValue(); if (Double.isNaN(val)) { - return Double.NaN; + if (!ignoreNaN) { + return Double.NaN; + } + } else { + sum += val; } - sum += val; } return sum; } - private boolean hasNaN() { - for (TbelCfTsDoubleVal value : values) { - if (Double.isNaN(value.getValue())) { - return true; - } - } - return false; - } - @JsonIgnore public int getSize() { return values.size();