Browse Source

added default value for metric

pull/14253/head
IrynaMatveieva 7 months ago
parent
commit
8087ca16ef
  1. 16
      application/src/main/java/org/thingsboard/server/service/cf/AbstractCalculatedFieldProcessingService.java
  2. 11
      application/src/main/java/org/thingsboard/server/utils/CalculatedFieldArgumentUtils.java
  3. 2
      application/src/main/resources/thingsboard.yml
  4. 1
      common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/aggregation/AggMetric.java
  5. 16
      ui-ngx/src/app/modules/home/components/calculated-fields/components/metrics/calculated-field-metrics-table.module.ts

16
application/src/main/java/org/thingsboard/server/service/cf/AbstractCalculatedFieldProcessingService.java

@ -23,6 +23,7 @@ import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.server.common.data.cf.configuration.Argument;
import org.thingsboard.server.common.data.cf.configuration.ArgumentType;
@ -53,7 +54,6 @@ import org.thingsboard.server.service.cf.ctx.state.ArgumentEntry;
import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldCtx;
import org.thingsboard.server.service.cf.ctx.state.SingleValueArgumentEntry;
import org.thingsboard.server.service.cf.ctx.state.aggregation.single.AggIntervalEntry;
import org.thingsboard.server.utils.CalculatedFieldArgumentUtils;
import java.util.Collections;
import java.util.HashMap;
@ -71,6 +71,7 @@ import static org.thingsboard.server.common.data.cf.configuration.geofencing.Ent
import static org.thingsboard.server.common.data.cf.configuration.geofencing.EntityCoordinates.ENTITY_ID_LONGITUDE_ARGUMENT_KEY;
import static org.thingsboard.server.utils.CalculatedFieldArgumentUtils.createDefaultAttributeEntry;
import static org.thingsboard.server.utils.CalculatedFieldArgumentUtils.createDefaultKvEntry;
import static org.thingsboard.server.utils.CalculatedFieldArgumentUtils.transformAggMetricArgument;
import static org.thingsboard.server.utils.CalculatedFieldArgumentUtils.transformAggregationArgument;
import static org.thingsboard.server.utils.CalculatedFieldArgumentUtils.transformSingleValueArgument;
import static org.thingsboard.server.utils.CalculatedFieldArgumentUtils.transformTsRollingArgument;
@ -87,6 +88,9 @@ public abstract class AbstractCalculatedFieldProcessingService {
protected ListeningExecutorService calculatedFieldCallbackExecutor;
@Value("${actors.calculated_fields.max_datapoints_limit}")
private int aggArgumentMaxDatapointsLimit;
@PostConstruct
public void init() {
calculatedFieldCallbackExecutor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(
@ -302,21 +306,21 @@ public abstract class AbstractCalculatedFieldProcessingService {
AggFunction function = metric.getFunction();
long intervalMs = interval.getEndTs() - interval.getStartTs();
BaseReadTsKvQuery query = new BaseReadTsKvQuery(argKey, interval.getStartTs(), interval.getEndTs(), intervalMs, 1, Aggregation.valueOf(function.name()));
ListenableFuture<ArgumentEntry> argumentEntryFut = fetchTimeSeriesInternal(tenantId, entityId, query, CalculatedFieldArgumentUtils::transformAggMetricArgument);
ListenableFuture<ArgumentEntry> argumentEntryFut = fetchTimeSeriesInternal(tenantId, entityId, query, timeSeries -> transformAggMetricArgument(timeSeries, argKey, metric));
return resolveArgumentValue(argKey, argumentEntryFut);
}
private ListenableFuture<ArgumentEntry> fetchTimeSeries(TenantId tenantId, EntityId entityId, Argument argument, AggInterval interval, long queryEndTs) {
long startInterval = interval.getCurrentIntervalStartTs();
long intervalEndTs = interval.getCurrentIntervalEndTs();
ReadTsKvQuery query = buildTimeSeriesQuery(tenantId, argument, startInterval, queryEndTs);
ReadTsKvQuery query = new BaseReadTsKvQuery(argument.getRefEntityKey().getKey(), startInterval, queryEndTs, 0, aggArgumentMaxDatapointsLimit, Aggregation.NONE);
return fetchTimeSeriesInternal(tenantId, entityId, query, timeSeries -> transformAggregationArgument(timeSeries, startInterval, intervalEndTs));
}
private ListenableFuture<ArgumentEntry> fetchTsRolling(TenantId tenantId, EntityId entityId, Argument argument, long queryEndTs) {
long argTimeWindow = argument.getTimeWindow() == 0 ? queryEndTs : argument.getTimeWindow();
long startInterval = queryEndTs - argTimeWindow;
ReadTsKvQuery query = buildTimeSeriesQuery(tenantId, argument, startInterval, queryEndTs);
ReadTsKvQuery query = buildTsRollingQuery(tenantId, argument, startInterval, queryEndTs);
return fetchTimeSeriesInternal(tenantId, entityId, query, tsRolling -> transformTsRollingArgument(tsRolling, query.getLimit(), argTimeWindow));
}
@ -352,10 +356,10 @@ public abstract class AbstractCalculatedFieldProcessingService {
}, calculatedFieldCallbackExecutor);
}
private ReadTsKvQuery buildTimeSeriesQuery(TenantId tenantId, Argument argument, long startTs, long endTs) {
private ReadTsKvQuery buildTsRollingQuery(TenantId tenantId, Argument argument, long startTs, long endTs) {
long maxDataPoints = apiLimitService.getLimit(
tenantId, DefaultTenantProfileConfiguration::getMaxDataPointsPerRollingArg);
int argumentLimit = argument.getLimit() == null ? 500000 : argument.getLimit();
int argumentLimit = argument.getLimit();
int limit = argumentLimit == 0 || argumentLimit > maxDataPoints ? (int) maxDataPoints : argumentLimit;
return new BaseReadTsKvQuery(argument.getRefEntityKey().getKey(), startTs, endTs, 0, limit, Aggregation.NONE);
}

11
application/src/main/java/org/thingsboard/server/utils/CalculatedFieldArgumentUtils.java

@ -21,6 +21,7 @@ import com.google.common.util.concurrent.MoreExecutors;
import org.apache.commons.lang3.math.NumberUtils;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.cf.configuration.Argument;
import org.thingsboard.server.common.data.cf.configuration.aggregation.AggMetric;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
@ -67,9 +68,9 @@ public class CalculatedFieldArgumentUtils {
return ArgumentEntry.createTsRollingArgument(tsRolling, limit, argTimeWindow);
}
public static ArgumentEntry transformAggMetricArgument(List<TsKvEntry> timeSeries) {
public static ArgumentEntry transformAggMetricArgument(List<TsKvEntry> timeSeries, String argKey, AggMetric aggMetric) {
if (timeSeries == null || timeSeries.isEmpty()) {
return new SingleValueArgumentEntry();
return ArgumentEntry.createSingleValueArgument(createDefaultKvEntry(argKey, aggMetric.getDefaultValue()));
}
return ArgumentEntry.createSingleValueArgument(timeSeries.get(0));
}
@ -86,8 +87,10 @@ public class CalculatedFieldArgumentUtils {
}
public static KvEntry createDefaultKvEntry(Argument argument) {
String key = argument.getRefEntityKey().getKey();
String defaultValue = argument.getDefaultValue();
return createDefaultKvEntry(argument.getRefEntityKey().getKey(), argument.getDefaultValue());
}
public static KvEntry createDefaultKvEntry(String key, String defaultValue) {
if (StringUtils.isBlank(defaultValue)) {
return new StringDataEntry(key, null);
}

2
application/src/main/resources/thingsboard.yml

@ -531,6 +531,8 @@ actors:
calculation_timeout: "${ACTORS_CALCULATION_TIMEOUT_SEC:5}"
# Interval in seconds to re-evaluate calculated fields that have a time schedule. 2 minutes by default.
check_interval: "${ACTORS_CALCULATED_FIELDS_CHECK_INTERVAL_SEC:120}"
# Maximum allowed datapoints fetched by aggregation calculated fields
max_datapoints_limit: "${CF_AGG_MAX_DATAPOINTS_LIMIT:50000}"
debug:
settings:

1
common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/aggregation/AggMetric.java

@ -27,5 +27,6 @@ public class AggMetric {
private AggFunction function;
private String filter;
private AggInput input;
private String defaultValue;
}

16
ui-ngx/src/app/modules/home/components/calculated-fields/components/metrics/calculated-field-metrics-table.module.ts

@ -1,3 +1,19 @@
///
/// Copyright © 2016-2025 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.
///
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from '@shared/shared.module';

Loading…
Cancel
Save