fixed functions
This commit is contained in:
parent
a52c578ecd
commit
72f26d9fe2
@ -25,7 +25,6 @@ import org.thingsboard.script.api.tbel.TbelCfTsDoubleVal;
|
|||||||
import org.thingsboard.script.api.tbel.TbelCfTsRollingArg;
|
import org.thingsboard.script.api.tbel.TbelCfTsRollingArg;
|
||||||
import org.thingsboard.server.common.data.kv.KvEntry;
|
import org.thingsboard.server.common.data.kv.KvEntry;
|
||||||
import org.thingsboard.server.common.data.kv.TsKvEntry;
|
import org.thingsboard.server.common.data.kv.TsKvEntry;
|
||||||
import org.thingsboard.server.exception.CalculatedFieldStateException;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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 STRING -> value.getStrValue().ifPresent(aString -> tsRecords.put(ts, Double.parseDouble(aString)));
|
||||||
case JSON -> value.getJsonValue().ifPresent(aString -> tsRecords.put(ts, Double.parseDouble(aString)));
|
case JSON -> value.getJsonValue().ifPresent(aString -> tsRecords.put(ts, Double.parseDouble(aString)));
|
||||||
}
|
}
|
||||||
cleanupExpiredRecords();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
tsRecords.put(ts, Double.NaN);
|
tsRecords.put(ts, Double.NaN);
|
||||||
log.debug("Invalid value '{}' for time series rolling arguments. Only numeric values are supported.", value.getValue());
|
log.debug("Invalid value '{}' for time series rolling arguments. Only numeric values are supported.", value.getValue());
|
||||||
|
} finally {
|
||||||
|
cleanupExpiredRecords();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,14 +61,18 @@ public class TbelCfTsRollingArg implements TbelCfArg, Iterable<TbelCfTsDoubleVal
|
|||||||
}
|
}
|
||||||
|
|
||||||
public double max() {
|
public double max() {
|
||||||
|
return max(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double max(boolean ignoreNaN) {
|
||||||
if (values.isEmpty()) {
|
if (values.isEmpty()) {
|
||||||
return 0;
|
throw new IllegalArgumentException("Rolling argument values are empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
double max = Double.MIN_VALUE;
|
double max = Double.MIN_VALUE;
|
||||||
for (TbelCfTsDoubleVal value : values) {
|
for (TbelCfTsDoubleVal value : values) {
|
||||||
double val = value.getValue();
|
double val = value.getValue();
|
||||||
if (Double.isNaN(val)) {
|
if (!ignoreNaN && Double.isNaN(val)) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
if (max < val) {
|
if (max < val) {
|
||||||
@ -79,14 +83,18 @@ public class TbelCfTsRollingArg implements TbelCfArg, Iterable<TbelCfTsDoubleVal
|
|||||||
}
|
}
|
||||||
|
|
||||||
public double min() {
|
public double min() {
|
||||||
|
return min(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double min(boolean ignoreNaN) {
|
||||||
if (values.isEmpty()) {
|
if (values.isEmpty()) {
|
||||||
return 0;
|
throw new IllegalArgumentException("Rolling argument values are empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
double min = Double.MAX_VALUE;
|
double min = Double.MAX_VALUE;
|
||||||
for (TbelCfTsDoubleVal value : values) {
|
for (TbelCfTsDoubleVal value : values) {
|
||||||
double val = value.getValue();
|
double val = value.getValue();
|
||||||
if (Double.isNaN(val)) {
|
if (!ignoreNaN && Double.isNaN(val)) {
|
||||||
return Double.NaN;
|
return Double.NaN;
|
||||||
}
|
}
|
||||||
if (min > val) {
|
if (min > val) {
|
||||||
@ -97,21 +105,28 @@ public class TbelCfTsRollingArg implements TbelCfArg, Iterable<TbelCfTsDoubleVal
|
|||||||
}
|
}
|
||||||
|
|
||||||
public double mean() {
|
public double mean() {
|
||||||
if (values.isEmpty()) {
|
return mean(true);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double sum = sum();
|
public double mean(boolean ignoreNaN) {
|
||||||
return Double.isNaN(sum) ? Double.NaN : sum / values.size();
|
if (values.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Rolling argument values are empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum(ignoreNaN) / count(ignoreNaN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double std() {
|
public double std() {
|
||||||
if (values.isEmpty()) {
|
return std(true);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double mean = mean();
|
public double std(boolean ignoreNaN) {
|
||||||
if (Double.isNaN(mean)) {
|
if (values.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Rolling argument values are empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
double mean = mean(ignoreNaN);
|
||||||
|
if (!ignoreNaN && Double.isNaN(mean)) {
|
||||||
return Double.NaN;
|
return Double.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,26 +134,36 @@ public class TbelCfTsRollingArg implements TbelCfArg, Iterable<TbelCfTsDoubleVal
|
|||||||
for (TbelCfTsDoubleVal value : values) {
|
for (TbelCfTsDoubleVal value : values) {
|
||||||
double val = value.getValue();
|
double val = value.getValue();
|
||||||
if (Double.isNaN(val)) {
|
if (Double.isNaN(val)) {
|
||||||
|
if (!ignoreNaN) {
|
||||||
return Double.NaN;
|
return Double.NaN;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
sum += Math.pow(val - mean, 2);
|
sum += Math.pow(val - mean, 2);
|
||||||
}
|
}
|
||||||
return Math.sqrt(sum / values.size());
|
}
|
||||||
|
return Math.sqrt(sum / count(ignoreNaN));
|
||||||
}
|
}
|
||||||
|
|
||||||
public double median() {
|
public double median() {
|
||||||
|
return median(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double median(boolean ignoreNaN) {
|
||||||
if (values.isEmpty()) {
|
if (values.isEmpty()) {
|
||||||
return 0;
|
throw new IllegalArgumentException("Rolling argument values are empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Double> sortedValues = new ArrayList<>();
|
List<Double> sortedValues = new ArrayList<>();
|
||||||
for (TbelCfTsDoubleVal value : values) {
|
for (TbelCfTsDoubleVal value : values) {
|
||||||
double val = value.getValue();
|
double val = value.getValue();
|
||||||
if (Double.isNaN(val)) {
|
if (Double.isNaN(val)) {
|
||||||
|
if (!ignoreNaN) {
|
||||||
return Double.NaN;
|
return Double.NaN;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
sortedValues.add(val);
|
sortedValues.add(val);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Collections.sort(sortedValues);
|
Collections.sort(sortedValues);
|
||||||
|
|
||||||
int size = sortedValues.size();
|
int size = sortedValues.size();
|
||||||
@ -147,51 +172,90 @@ public class TbelCfTsRollingArg implements TbelCfArg, Iterable<TbelCfTsDoubleVal
|
|||||||
: (sortedValues.get(size / 2 - 1) + sortedValues.get(size / 2)) / 2.0;
|
: (sortedValues.get(size / 2 - 1) + sortedValues.get(size / 2)) / 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double count() {
|
public int count() {
|
||||||
return hasNaN() ? Double.NaN : values.size();
|
return count(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int count(boolean ignoreNaN) {
|
||||||
|
int count = 0;
|
||||||
|
if (ignoreNaN) {
|
||||||
|
for (TbelCfTsDoubleVal value : values) {
|
||||||
|
if (!Double.isNaN(value.getValue())) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
return values.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double last() {
|
public double last() {
|
||||||
if (values.isEmpty()) {
|
return last(true);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasNaN() ? Double.NaN : values.get(values.size() - 1).getValue();
|
public double last(boolean ignoreNaN) {
|
||||||
|
if (values.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Rolling argument values are empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
double value = values.get(values.size() - 1).getValue();
|
||||||
|
if (!Double.isNaN(value) || !ignoreNaN) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
for (int i = values.size() - 2; i >= 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() {
|
public double first() {
|
||||||
if (values.isEmpty()) {
|
return first(true);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasNaN() ? Double.NaN : values.get(0).getValue();
|
public double first(boolean ignoreNaN) {
|
||||||
|
if (values.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Rolling argument values are empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
public double sum() {
|
||||||
|
return sum(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double sum(boolean ignoreNaN) {
|
||||||
if (values.isEmpty()) {
|
if (values.isEmpty()) {
|
||||||
return 0;
|
throw new IllegalArgumentException("Rolling argument values are empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
for (TbelCfTsDoubleVal value : values) {
|
for (TbelCfTsDoubleVal value : values) {
|
||||||
double val = value.getValue();
|
double val = value.getValue();
|
||||||
if (Double.isNaN(val)) {
|
if (Double.isNaN(val)) {
|
||||||
|
if (!ignoreNaN) {
|
||||||
return Double.NaN;
|
return Double.NaN;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
sum += val;
|
sum += val;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasNaN() {
|
|
||||||
for (TbelCfTsDoubleVal value : values) {
|
|
||||||
if (Double.isNaN(value.getValue())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
return values.size();
|
return values.size();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user