Commit a15e991d23d9bd421fdfa673f170418d5fe2d5fd
1 parent
6c1074a8
Added support of BigDecimal to the JsonConverter
Showing
3 changed files
with
90 additions
and
11 deletions
... | ... | @@ -51,6 +51,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCre |
51 | 51 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; |
52 | 52 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; |
53 | 53 | |
54 | +import java.math.BigDecimal; | |
54 | 55 | import java.util.ArrayList; |
55 | 56 | import java.util.HashMap; |
56 | 57 | import java.util.HashSet; |
... | ... | @@ -245,12 +246,25 @@ public class JsonConverter { |
245 | 246 | } |
246 | 247 | |
247 | 248 | private static void parseNumericValue(List<KvEntry> result, Entry<String, JsonElement> valueEntry, JsonPrimitive value) { |
248 | - if (value.getAsString().contains(".")) { | |
249 | - result.add(new DoubleDataEntry(valueEntry.getKey(), value.getAsDouble())); | |
249 | + String valueAsString = value.getAsString(); | |
250 | + String key = valueEntry.getKey(); | |
251 | + if (valueAsString.contains("e") || valueAsString.contains("E")) { | |
252 | + var bd = new BigDecimal(valueAsString); | |
253 | + if (bd.stripTrailingZeros().scale() <= 0) { | |
254 | + try { | |
255 | + result.add(new LongDataEntry(key, bd.longValueExact())); | |
256 | + } catch (ArithmeticException e) { | |
257 | + result.add(new DoubleDataEntry(key, bd.doubleValue())); | |
258 | + } | |
259 | + } else { | |
260 | + result.add(new DoubleDataEntry(key, bd.doubleValue())); | |
261 | + } | |
262 | + } else if (valueAsString.contains(".")) { | |
263 | + result.add(new DoubleDataEntry(key, value.getAsDouble())); | |
250 | 264 | } else { |
251 | 265 | try { |
252 | 266 | long longValue = Long.parseLong(value.getAsString()); |
253 | - result.add(new LongDataEntry(valueEntry.getKey(), longValue)); | |
267 | + result.add(new LongDataEntry(key, longValue)); | |
254 | 268 | } catch (NumberFormatException e) { |
255 | 269 | throw new JsonSyntaxException("Big integer values are not supported!"); |
256 | 270 | } |
... | ... | @@ -285,7 +299,8 @@ public class JsonConverter { |
285 | 299 | return result; |
286 | 300 | } |
287 | 301 | |
288 | - public static JsonObject getJsonObjectForGateway(String deviceName, TransportProtos.GetAttributeResponseMsg responseMsg) { | |
302 | + public static JsonObject getJsonObjectForGateway(String deviceName, TransportProtos.GetAttributeResponseMsg | |
303 | + responseMsg) { | |
289 | 304 | JsonObject result = new JsonObject(); |
290 | 305 | result.addProperty("id", responseMsg.getRequestId()); |
291 | 306 | result.addProperty(DEVICE_PROPERTY, deviceName); |
... | ... | @@ -298,7 +313,8 @@ public class JsonConverter { |
298 | 313 | return result; |
299 | 314 | } |
300 | 315 | |
301 | - public static JsonObject getJsonObjectForGateway(String deviceName, AttributeUpdateNotificationMsg notificationMsg) { | |
316 | + public static JsonObject getJsonObjectForGateway(String deviceName, AttributeUpdateNotificationMsg | |
317 | + notificationMsg) { | |
302 | 318 | JsonObject result = new JsonObject(); |
303 | 319 | result.addProperty(DEVICE_PROPERTY, deviceName); |
304 | 320 | result.add("data", toJson(notificationMsg)); |
... | ... | @@ -446,7 +462,8 @@ public class JsonConverter { |
446 | 462 | return result; |
447 | 463 | } |
448 | 464 | |
449 | - public static JsonElement toGatewayJson(String deviceName, TransportProtos.ProvisionDeviceResponseMsg responseRequest) { | |
465 | + public static JsonElement toGatewayJson(String deviceName, TransportProtos.ProvisionDeviceResponseMsg | |
466 | + responseRequest) { | |
450 | 467 | JsonObject result = new JsonObject(); |
451 | 468 | result.addProperty(DEVICE_PROPERTY, deviceName); |
452 | 469 | result.add("data", JsonConverter.toJson(responseRequest)); |
... | ... | @@ -496,15 +513,18 @@ public class JsonConverter { |
496 | 513 | return result; |
497 | 514 | } |
498 | 515 | |
499 | - public static Map<Long, List<KvEntry>> convertToTelemetry(JsonElement jsonElement, long systemTs) throws JsonSyntaxException { | |
516 | + public static Map<Long, List<KvEntry>> convertToTelemetry(JsonElement jsonElement, long systemTs) throws | |
517 | + JsonSyntaxException { | |
500 | 518 | return convertToTelemetry(jsonElement, systemTs, false); |
501 | 519 | } |
502 | 520 | |
503 | - public static Map<Long, List<KvEntry>> convertToSortedTelemetry(JsonElement jsonElement, long systemTs) throws JsonSyntaxException { | |
521 | + public static Map<Long, List<KvEntry>> convertToSortedTelemetry(JsonElement jsonElement, long systemTs) throws | |
522 | + JsonSyntaxException { | |
504 | 523 | return convertToTelemetry(jsonElement, systemTs, true); |
505 | 524 | } |
506 | 525 | |
507 | - public static Map<Long, List<KvEntry>> convertToTelemetry(JsonElement jsonElement, long systemTs, boolean sorted) throws JsonSyntaxException { | |
526 | + public static Map<Long, List<KvEntry>> convertToTelemetry(JsonElement jsonElement, long systemTs, boolean sorted) throws | |
527 | + JsonSyntaxException { | |
508 | 528 | Map<Long, List<KvEntry>> result = sorted ? new TreeMap<>() : new HashMap<>(); |
509 | 529 | convertToTelemetry(jsonElement, systemTs, result, null); |
510 | 530 | return result; |
... | ... | @@ -574,7 +594,8 @@ public class JsonConverter { |
574 | 594 | .build(); |
575 | 595 | } |
576 | 596 | |
577 | - private static TransportProtos.ProvisionDeviceCredentialsMsg buildProvisionDeviceCredentialsMsg(String provisionKey, String provisionSecret) { | |
597 | + private static TransportProtos.ProvisionDeviceCredentialsMsg buildProvisionDeviceCredentialsMsg(String | |
598 | + provisionKey, String provisionSecret) { | |
578 | 599 | return TransportProtos.ProvisionDeviceCredentialsMsg.newBuilder() |
579 | 600 | .setProvisionDeviceKey(provisionKey) |
580 | 601 | .setProvisionDeviceSecret(provisionSecret) | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2021 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | + | |
17 | +import com.google.gson.JsonParser; | |
18 | +import org.junit.Assert; | |
19 | +import org.junit.Test; | |
20 | +import org.junit.runner.RunWith; | |
21 | +import org.mockito.junit.MockitoJUnitRunner; | |
22 | +import org.thingsboard.server.common.transport.adaptor.JsonConverter; | |
23 | + | |
24 | +@RunWith(MockitoJUnitRunner.class) | |
25 | +public class JsonConverterTest { | |
26 | + | |
27 | + private static final JsonParser JSON_PARSER = new JsonParser(); | |
28 | + | |
29 | + @Test | |
30 | + public void testParseBigDecimalAsLong() { | |
31 | + var result = JsonConverter.convertToTelemetry(JSON_PARSER.parse("{\"meterReadingDelta\": 1E+1}"), 0L); | |
32 | + Assert.assertEquals(10L, result.get(0L).get(0).getLongValue().get().longValue()); | |
33 | + } | |
34 | + | |
35 | + @Test | |
36 | + public void testParseBigDecimalAsDouble() { | |
37 | + var result = JsonConverter.convertToTelemetry(JSON_PARSER.parse("{\"meterReadingDelta\": 101E-1}"), 0L); | |
38 | + Assert.assertEquals(10.1, result.get(0L).get(0).getDoubleValue().get(), 0.0); | |
39 | + } | |
40 | + | |
41 | + @Test | |
42 | + public void testParseAsDouble() { | |
43 | + var result = JsonConverter.convertToTelemetry(JSON_PARSER.parse("{\"meterReadingDelta\": 1.1}"), 0L); | |
44 | + Assert.assertEquals(1.1, result.get(0L).get(0).getDoubleValue().get(), 0.0); | |
45 | + } | |
46 | + | |
47 | + @Test | |
48 | + public void testParseAsLong() { | |
49 | + var result = JsonConverter.convertToTelemetry(JSON_PARSER.parse("{\"meterReadingDelta\": 11}"), 0L); | |
50 | + Assert.assertEquals(11L, result.get(0L).get(0).getLongValue().get().longValue()); | |
51 | + } | |
52 | + | |
53 | +} | ... | ... |
... | ... | @@ -93,12 +93,17 @@ public class CalculateDeltaNode implements TbNode { |
93 | 93 | return; |
94 | 94 | } |
95 | 95 | |
96 | + | |
96 | 97 | if (config.getRound() != null) { |
97 | 98 | delta = delta.setScale(config.getRound(), RoundingMode.HALF_UP); |
98 | 99 | } |
99 | 100 | |
100 | 101 | ObjectNode result = (ObjectNode) json; |
101 | - result.put(config.getOutputValueKey(), delta); | |
102 | + if (delta.stripTrailingZeros().scale() > 0) { | |
103 | + result.put(config.getOutputValueKey(), delta.doubleValue()); | |
104 | + } else { | |
105 | + result.put(config.getOutputValueKey(), delta.longValueExact()); | |
106 | + } | |
102 | 107 | |
103 | 108 | if (config.isAddPeriodBetweenMsgs()) { |
104 | 109 | long period = previousData != null ? currentTs - previousData.ts : 0; | ... | ... |