From bf656d2926aebe035abd8dc458c52b87f6a47ea2 Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Tue, 13 Jan 2026 10:35:23 +0200 Subject: [PATCH] created new number utils class --- .../ctx/state/SimpleCalculatedFieldState.java | 4 +-- .../aggregation/function/AvgAggEntry.java | 4 +-- .../aggregation/function/MaxAggEntry.java | 4 +-- .../aggregation/function/MinAggEntry.java | 4 +-- .../aggregation/function/SumAggEntry.java | 4 +-- ...EntityAggregationCalculatedFieldState.java | 4 +-- .../thingsboard/server/utils/NumberUtils.java | 33 +++++++++++++++++++ .../server/utils/NumberUtilsTest.java | 32 ++++++++++++++++++ .../thingsboard/script/api/tbel/TbUtils.java | 12 ------- .../script/api/tbel/TbUtilsTest.java | 7 ---- 10 files changed, 77 insertions(+), 31 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/utils/NumberUtils.java create mode 100644 application/src/test/java/org/thingsboard/server/utils/NumberUtilsTest.java diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java index 63f398bbdc..d05276d835 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java @@ -22,13 +22,13 @@ import com.google.common.util.concurrent.ListenableFuture; import lombok.EqualsAndHashCode; import net.objecthunter.exp4j.Expression; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.script.api.tbel.TbUtils; import org.thingsboard.server.actors.TbActorRef; import org.thingsboard.server.common.data.cf.CalculatedFieldType; import org.thingsboard.server.common.data.cf.configuration.Output; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.service.cf.CalculatedFieldResult; import org.thingsboard.server.service.cf.TelemetryCalculatedFieldResult; +import org.thingsboard.server.utils.NumberUtils; import java.util.Map; @@ -52,7 +52,7 @@ public class SimpleCalculatedFieldState extends BaseCalculatedFieldState { double expressionResult = ctx.evaluateSimpleExpression(expression.get(), this); Output output = ctx.getOutput(); - Object result = TbUtils.roundResult(expressionResult, output.getDecimalsByDefault()); + Object result = NumberUtils.roundResult(expressionResult, output.getDecimalsByDefault()); JsonNode outputResult = createResultJson(ctx.isUseLatestTs(), output.getName(), result); return Futures.immediateFuture(TelemetryCalculatedFieldResult.builder() diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/AvgAggEntry.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/AvgAggEntry.java index ee06ae1529..09985eab8d 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/AvgAggEntry.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/AvgAggEntry.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.service.cf.ctx.state.aggregation.function; -import org.thingsboard.script.api.tbel.TbUtils; import org.thingsboard.server.common.data.cf.configuration.aggregation.AggFunction; +import org.thingsboard.server.utils.NumberUtils; import java.math.BigDecimal; import java.math.RoundingMode; @@ -37,7 +37,7 @@ public class AvgAggEntry extends BaseAggEntry { @Override protected Object prepareResult(Integer precision) { double result = sum.divide(BigDecimal.valueOf(count), RoundingMode.HALF_UP).doubleValue(); - return TbUtils.roundResult(result, precision); + return NumberUtils.roundResult(result, precision); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/MaxAggEntry.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/MaxAggEntry.java index b006d8fcd9..0cc3bc4621 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/MaxAggEntry.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/MaxAggEntry.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.service.cf.ctx.state.aggregation.function; -import org.thingsboard.script.api.tbel.TbUtils; import org.thingsboard.server.common.data.cf.configuration.aggregation.AggFunction; +import org.thingsboard.server.utils.NumberUtils; public class MaxAggEntry extends BaseAggEntry { @@ -31,7 +31,7 @@ public class MaxAggEntry extends BaseAggEntry { @Override protected Object prepareResult(Integer precision) { - return TbUtils.roundResult(max, precision); + return NumberUtils.roundResult(max, precision); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/MinAggEntry.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/MinAggEntry.java index 2ce561d381..19ea27fb5b 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/MinAggEntry.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/MinAggEntry.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.service.cf.ctx.state.aggregation.function; -import org.thingsboard.script.api.tbel.TbUtils; import org.thingsboard.server.common.data.cf.configuration.aggregation.AggFunction; +import org.thingsboard.server.utils.NumberUtils; public class MinAggEntry extends BaseAggEntry { @@ -31,7 +31,7 @@ public class MinAggEntry extends BaseAggEntry { @Override protected Object prepareResult(Integer precision) { - return TbUtils.roundResult(min, precision); + return NumberUtils.roundResult(min, precision); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/SumAggEntry.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/SumAggEntry.java index 3639e36249..9776c977f6 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/SumAggEntry.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/function/SumAggEntry.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.service.cf.ctx.state.aggregation.function; -import org.thingsboard.script.api.tbel.TbUtils; import org.thingsboard.server.common.data.cf.configuration.aggregation.AggFunction; +import org.thingsboard.server.utils.NumberUtils; import java.math.BigDecimal; @@ -33,7 +33,7 @@ public class SumAggEntry extends BaseAggEntry { @Override protected Object prepareResult(Integer precision) { - return TbUtils.roundResult(sum.doubleValue(), precision); + return NumberUtils.roundResult(sum.doubleValue(), precision); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/single/EntityAggregationCalculatedFieldState.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/single/EntityAggregationCalculatedFieldState.java index 1297a22478..2676461637 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/single/EntityAggregationCalculatedFieldState.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/single/EntityAggregationCalculatedFieldState.java @@ -23,7 +23,6 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.common.util.DebugModeUtil; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.script.api.tbel.TbUtils; import org.thingsboard.script.api.tbel.TbelCfArg; import org.thingsboard.server.actors.TbActorRef; import org.thingsboard.server.common.data.cf.CalculatedFieldType; @@ -41,6 +40,7 @@ import org.thingsboard.server.service.cf.ctx.state.ArgumentEntry; import org.thingsboard.server.service.cf.ctx.state.BaseCalculatedFieldState; import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldCtx; import org.thingsboard.server.service.cf.ctx.state.SingleValueArgumentEntry; +import org.thingsboard.server.utils.NumberUtils; import java.time.Instant; import java.time.ZoneId; @@ -291,7 +291,7 @@ public class EntityAggregationCalculatedFieldState extends BaseCalculatedFieldSt ArgumentEntry argumentEntry = entry.getValue(); if (!argumentEntry.isEmpty()) { Object resultValue = argumentEntry.getValue() instanceof Number number - ? TbUtils.roundResult(number.doubleValue(), precision) + ? NumberUtils.roundResult(number.doubleValue(), precision) : argumentEntry.getValue(); metricsNode.put(metricName, JacksonUtil.toString(resultValue)); } diff --git a/application/src/main/java/org/thingsboard/server/utils/NumberUtils.java b/application/src/main/java/org/thingsboard/server/utils/NumberUtils.java new file mode 100644 index 0000000000..e34e7039c9 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/utils/NumberUtils.java @@ -0,0 +1,33 @@ +/** + * Copyright © 2016-2026 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.utils; + +import static org.thingsboard.script.api.tbel.TbUtils.toFixed; +import static org.thingsboard.script.api.tbel.TbUtils.toInt; + +public class NumberUtils { + + public static Object roundResult(double value, Integer precision) { + if (precision == null) { + return value; + } + if (precision.equals(0)) { + return toInt(value); + } + return toFixed(value, precision); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/utils/NumberUtilsTest.java b/application/src/test/java/org/thingsboard/server/utils/NumberUtilsTest.java new file mode 100644 index 0000000000..3708182120 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/utils/NumberUtilsTest.java @@ -0,0 +1,32 @@ +/** + * Copyright © 2016-2026 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.utils; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class NumberUtilsTest { + + private final double doubleVal = 1729.1729; + + @Test + public void roundResult() { + Assertions.assertEquals(1729.1729, NumberUtils.roundResult(doubleVal, null)); + Assertions.assertEquals(1729, NumberUtils.roundResult(doubleVal, 0)); + Assertions.assertEquals(1729.17, NumberUtils.roundResult(doubleVal, 2)); + } + +} diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index c0bdf122c3..6340b02dd0 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -264,8 +264,6 @@ public class TbUtils { float.class, int.class))); parserConfig.addImport("toInt", new MethodStub(TbUtils.class.getMethod("toInt", double.class))); - parserConfig.addImport("roundResult", new MethodStub(TbUtils.class.getMethod("roundResult", - double.class, Integer.class))); parserConfig.addImport("isNaN", new MethodStub(TbUtils.class.getMethod("isNaN", double.class))); parserConfig.addImport("hexToBytes", new MethodStub(TbUtils.class.getMethod("hexToBytes", @@ -1188,16 +1186,6 @@ public class TbUtils { return BigDecimal.valueOf(value).setScale(0, RoundingMode.HALF_UP).intValue(); } - public static Object roundResult(double value, Integer precision) { - if (precision == null) { - return value; - } - if (precision.equals(0)) { - return toInt(value); - } - return toFixed(value, precision); - } - public static boolean isNaN(double value) { return Double.isNaN(value); } diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java index 9feeb414dc..01ccd5d579 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java @@ -1154,13 +1154,6 @@ public class TbUtilsTest { Assertions.assertEquals(28, TbUtils.toInt(28.0)); } - @Test - public void roundResult() { - Assertions.assertEquals(1729.1729, TbUtils.roundResult(doubleVal, null)); - Assertions.assertEquals(1729, TbUtils.roundResult(doubleVal, 0)); - Assertions.assertEquals(1729.17, TbUtils.roundResult(doubleVal, 2)); - } - @Test public void isNaN() { assertFalse(TbUtils.isNaN(doubleVal));