|
@@ -182,11 +182,12 @@ public class TelemetryController extends BaseController { |
|
@@ -182,11 +182,12 @@ public class TelemetryController extends BaseController { |
182
|
@ResponseBody
|
182
|
@ResponseBody
|
183
|
public DeferredResult<ResponseEntity> getLatestTimeseries(
|
183
|
public DeferredResult<ResponseEntity> getLatestTimeseries(
|
184
|
@PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr,
|
184
|
@PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr,
|
185
|
- @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException {
|
185
|
+ @RequestParam(name = "keys", required = false) String keysStr,
|
|
|
186
|
+ @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException {
|
186
|
SecurityUser user = getCurrentUser();
|
187
|
SecurityUser user = getCurrentUser();
|
187
|
|
188
|
|
188
|
return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr,
|
189
|
return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr,
|
189
|
- (result, tenantId, entityId) -> getLatestTimeseriesValuesCallback(result, user, entityId, keysStr));
|
190
|
+ (result, tenantId, entityId) -> getLatestTimeseriesValuesCallback(result, user, entityId, keysStr, useStrictDataTypes));
|
190
|
}
|
191
|
}
|
191
|
|
192
|
|
192
|
|
193
|
|
|
@@ -200,8 +201,8 @@ public class TelemetryController extends BaseController { |
|
@@ -200,8 +201,8 @@ public class TelemetryController extends BaseController { |
200
|
@RequestParam(name = "endTs") Long endTs,
|
201
|
@RequestParam(name = "endTs") Long endTs,
|
201
|
@RequestParam(name = "interval", defaultValue = "0") Long interval,
|
202
|
@RequestParam(name = "interval", defaultValue = "0") Long interval,
|
202
|
@RequestParam(name = "limit", defaultValue = "100") Integer limit,
|
203
|
@RequestParam(name = "limit", defaultValue = "100") Integer limit,
|
203
|
- @RequestParam(name = "agg", defaultValue = "NONE") String aggStr
|
|
|
204
|
- ) throws ThingsboardException {
|
204
|
+ @RequestParam(name = "agg", defaultValue = "NONE") String aggStr,
|
|
|
205
|
+ @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException {
|
205
|
return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr,
|
206
|
return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr,
|
206
|
(result, tenantId, entityId) -> {
|
207
|
(result, tenantId, entityId) -> {
|
207
|
// If interval is 0, convert this to a NONE aggregation, which is probably what the user really wanted
|
208
|
// If interval is 0, convert this to a NONE aggregation, which is probably what the user really wanted
|
|
@@ -209,7 +210,7 @@ public class TelemetryController extends BaseController { |
|
@@ -209,7 +210,7 @@ public class TelemetryController extends BaseController { |
209
|
List<ReadTsKvQuery> queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, agg))
|
210
|
List<ReadTsKvQuery> queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, agg))
|
210
|
.collect(Collectors.toList());
|
211
|
.collect(Collectors.toList());
|
211
|
|
212
|
|
212
|
- Futures.addCallback(tsService.findAll(tenantId, entityId, queries), getTsKvListCallback(result));
|
213
|
+ Futures.addCallback(tsService.findAll(tenantId, entityId, queries), getTsKvListCallback(result, useStrictDataTypes));
|
213
|
});
|
214
|
});
|
214
|
}
|
215
|
}
|
215
|
|
216
|
|
|
@@ -454,14 +455,14 @@ public class TelemetryController extends BaseController { |
|
@@ -454,14 +455,14 @@ public class TelemetryController extends BaseController { |
454
|
});
|
455
|
});
|
455
|
}
|
456
|
}
|
456
|
|
457
|
|
457
|
- private void getLatestTimeseriesValuesCallback(@Nullable DeferredResult<ResponseEntity> result, SecurityUser user, EntityId entityId, String keys) {
|
458
|
+ private void getLatestTimeseriesValuesCallback(@Nullable DeferredResult<ResponseEntity> result, SecurityUser user, EntityId entityId, String keys, Boolean useStrictDataTypes) {
|
458
|
ListenableFuture<List<TsKvEntry>> future;
|
459
|
ListenableFuture<List<TsKvEntry>> future;
|
459
|
if (StringUtils.isEmpty(keys)) {
|
460
|
if (StringUtils.isEmpty(keys)) {
|
460
|
future = tsService.findAllLatest(user.getTenantId(), entityId);
|
461
|
future = tsService.findAllLatest(user.getTenantId(), entityId);
|
461
|
} else {
|
462
|
} else {
|
462
|
future = tsService.findLatest(user.getTenantId(), entityId, toKeysList(keys));
|
463
|
future = tsService.findLatest(user.getTenantId(), entityId, toKeysList(keys));
|
463
|
}
|
464
|
}
|
464
|
- Futures.addCallback(future, getTsKvListCallback(result));
|
465
|
+ Futures.addCallback(future, getTsKvListCallback(result, useStrictDataTypes));
|
465
|
}
|
466
|
}
|
466
|
|
467
|
|
467
|
private void getAttributeValuesCallback(@Nullable DeferredResult<ResponseEntity> result, SecurityUser user, EntityId entityId, String scope, String keys) {
|
468
|
private void getAttributeValuesCallback(@Nullable DeferredResult<ResponseEntity> result, SecurityUser user, EntityId entityId, String scope, String keys) {
|
|
@@ -544,7 +545,7 @@ public class TelemetryController extends BaseController { |
|
@@ -544,7 +545,7 @@ public class TelemetryController extends BaseController { |
544
|
@Override
|
545
|
@Override
|
545
|
public void onSuccess(List<AttributeKvEntry> attributes) {
|
546
|
public void onSuccess(List<AttributeKvEntry> attributes) {
|
546
|
List<AttributeData> values = attributes.stream().map(attribute ->
|
547
|
List<AttributeData> values = attributes.stream().map(attribute ->
|
547
|
- new AttributeData(attribute.getLastUpdateTs(), attribute.getKey(), getKvValue(attribute))
|
548
|
+ new AttributeData(attribute.getLastUpdateTs(), attribute.getKey(), getKvValue(attribute))
|
548
|
).collect(Collectors.toList());
|
549
|
).collect(Collectors.toList());
|
549
|
logAttributesRead(user, entityId, scope, keyList, null);
|
550
|
logAttributesRead(user, entityId, scope, keyList, null);
|
550
|
response.setResult(new ResponseEntity<>(values, HttpStatus.OK));
|
551
|
response.setResult(new ResponseEntity<>(values, HttpStatus.OK));
|
|
@@ -559,14 +560,14 @@ public class TelemetryController extends BaseController { |
|
@@ -559,14 +560,14 @@ public class TelemetryController extends BaseController { |
559
|
};
|
560
|
};
|
560
|
}
|
561
|
}
|
561
|
|
562
|
|
562
|
- private FutureCallback<List<TsKvEntry>> getTsKvListCallback(final DeferredResult<ResponseEntity> response) {
|
563
|
+ private FutureCallback<List<TsKvEntry>> getTsKvListCallback(final DeferredResult<ResponseEntity> response, Boolean useStrictDataTypes) {
|
563
|
return new FutureCallback<List<TsKvEntry>>() {
|
564
|
return new FutureCallback<List<TsKvEntry>>() {
|
564
|
@Override
|
565
|
@Override
|
565
|
public void onSuccess(List<TsKvEntry> data) {
|
566
|
public void onSuccess(List<TsKvEntry> data) {
|
566
|
Map<String, List<TsData>> result = new LinkedHashMap<>();
|
567
|
Map<String, List<TsData>> result = new LinkedHashMap<>();
|
567
|
for (TsKvEntry entry : data) {
|
568
|
for (TsKvEntry entry : data) {
|
568
|
- result.computeIfAbsent(entry.getKey(), k -> new ArrayList<>())
|
|
|
569
|
- .add(new TsData(entry.getTs(), entry.getValueAsString()));
|
569
|
+ Object value = useStrictDataTypes ? getKvValue(entry) : entry.getValueAsString();
|
|
|
570
|
+ result.computeIfAbsent(entry.getKey(), k -> new ArrayList<>()).add(new TsData(entry.getTs(), value));
|
570
|
}
|
571
|
}
|
571
|
response.setResult(new ResponseEntity<>(result, HttpStatus.OK));
|
572
|
response.setResult(new ResponseEntity<>(result, HttpStatus.OK));
|
572
|
}
|
573
|
}
|