From 0d0ca90cf96cd63a2da79ee28e93110434a18734 Mon Sep 17 00:00:00 2001 From: thingsboard648 Date: Tue, 5 Mar 2024 10:38:19 +0200 Subject: [PATCH] added property to ignore delta in output messages if it is zero --- .../engine/metadata/CalculateDeltaNode.java | 27 +++++++++- .../CalculateDeltaNodeConfiguration.java | 3 +- .../metadata/CalculateDeltaNodeTest.java | 54 ++++++++++++++++++- 3 files changed, 80 insertions(+), 4 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/CalculateDeltaNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/CalculateDeltaNode.java index 609888db84..510d089372 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/CalculateDeltaNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/CalculateDeltaNode.java @@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.msg.TbNodeConnectionType; import org.thingsboard.server.common.data.plugin.ComponentType; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.dao.timeseries.TimeseriesService; @@ -46,7 +47,9 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; @Slf4j @RuleNode(type = ComponentType.ENRICHMENT, - name = "calculate delta", relationTypes = {TbNodeConnectionType.SUCCESS, TbNodeConnectionType.FAILURE, TbNodeConnectionType.OTHER}, + name = "calculate delta", + version = 1, + relationTypes = {TbNodeConnectionType.SUCCESS, TbNodeConnectionType.FAILURE, TbNodeConnectionType.OTHER}, configClazz = CalculateDeltaNodeConfiguration.class, nodeDescription = "Calculates delta and amount of time passed between previous timeseries key reading " + "and current value for this key from the incoming message", @@ -96,6 +99,11 @@ public class CalculateDeltaNode implements TbNode { BigDecimal delta = BigDecimal.valueOf(previousData != null ? currentValue - previousData.value : 0.0); + if (config.isOnlyComputeTrueDeltas() && delta.doubleValue() == 0) { + ctx.tellSuccess(msg); + return; + } + if (config.isTellFailureIfDeltaIsNegative() && delta.doubleValue() < 0) { ctx.tellFailure(msg, new IllegalArgumentException("Delta value is negative!")); return; @@ -128,6 +136,23 @@ public class CalculateDeltaNode implements TbNode { } } + @Override + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + boolean hasChanges = false; + switch (fromVersion) { + case 0: + String onlyComputeTrueDeltas = "onlyComputeTrueDeltas"; + if (!oldConfiguration.has(onlyComputeTrueDeltas)) { + hasChanges = true; + ((ObjectNode) oldConfiguration).put(onlyComputeTrueDeltas, false); + } + break; + default: + break; + } + return new TbPair<>(hasChanges, oldConfiguration); + } + private ListenableFuture fetchLatestValueAsync(EntityId entityId) { return Futures.transform(timeseriesService.findLatest(ctx.getTenantId(), entityId, Collections.singletonList(config.getInputValueKey())), list -> extractValue(list.get(0)) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/CalculateDeltaNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/CalculateDeltaNodeConfiguration.java index 0c4e6de556..9f30aae22b 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/CalculateDeltaNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/CalculateDeltaNodeConfiguration.java @@ -30,6 +30,7 @@ public class CalculateDeltaNodeConfiguration implements NodeConfiguration givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig() { + return Stream.of( + // default config for version 0 + Arguments.of(0, + "{\"inputValueKey\":\"pulseCounter\",\"outputValueKey\":\"delta\",\"useCache\":true,\"addPeriodBetweenMsgs\":false, \"periodValueKey\":\"periodInMs\", \"round\":null,\"tellFailureIfDeltaIsNegative\":true}", + true, + "{\"inputValueKey\":\"pulseCounter\",\"outputValueKey\":\"delta\",\"useCache\":true,\"addPeriodBetweenMsgs\":false, \"periodValueKey\":\"periodInMs\", \"round\":null,\"tellFailureIfDeltaIsNegative\":true, \"onlyComputeTrueDeltas\":false}"), + // default config for version 1 with upgrade from version 0 + Arguments.of(1, + "{\"inputValueKey\":\"pulseCounter\",\"outputValueKey\":\"delta\",\"useCache\":true,\"addPeriodBetweenMsgs\":false, \"periodValueKey\":\"periodInMs\", \"round\":null,\"tellFailureIfDeltaIsNegative\":true, \"onlyComputeTrueDeltas\":false}", + false, + "{\"inputValueKey\":\"pulseCounter\",\"outputValueKey\":\"delta\",\"useCache\":true,\"addPeriodBetweenMsgs\":false, \"periodValueKey\":\"periodInMs\", \"round\":null,\"tellFailureIfDeltaIsNegative\":true, \"onlyComputeTrueDeltas\":false}") + ); + + } + + @Override + protected TbNode getTestNode() { + return node; + } }