refactored service and test classes
This commit is contained in:
		
							parent
							
								
									86dd8e725b
								
							
						
					
					
						commit
						444c5bf079
					
				@ -38,7 +38,7 @@ import org.thingsboard.server.common.data.cf.BaseCalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldLink;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFiledLinkConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldLinkConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
 | 
			
		||||
import org.thingsboard.server.common.data.id.AssetId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.AssetProfileId;
 | 
			
		||||
@ -58,8 +58,6 @@ import org.thingsboard.server.dao.timeseries.TimeseriesService;
 | 
			
		||||
import org.thingsboard.server.gen.transport.TransportProtos;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
 | 
			
		||||
import org.thingsboard.server.service.profile.TbAssetProfileCache;
 | 
			
		||||
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
 | 
			
		||||
import org.thingsboard.server.service.security.model.SecurityUser;
 | 
			
		||||
import org.thingsboard.server.service.security.permission.Operation;
 | 
			
		||||
 | 
			
		||||
@ -84,8 +82,6 @@ import static org.thingsboard.server.dao.service.Validator.validateEntityId;
 | 
			
		||||
public class DefaultTbCalculatedFieldService extends AbstractTbEntityService implements TbCalculatedFieldService {
 | 
			
		||||
 | 
			
		||||
    private final CalculatedFieldService calculatedFieldService;
 | 
			
		||||
    private final TbDeviceProfileCache deviceProfileCache;
 | 
			
		||||
    private final TbAssetProfileCache assetProfileCache;
 | 
			
		||||
    private final AttributesService attributesService;
 | 
			
		||||
    private final TimeseriesService timeseriesService;
 | 
			
		||||
    private ListeningScheduledExecutorService scheduledExecutor;
 | 
			
		||||
@ -215,6 +211,15 @@ public class DefaultTbCalculatedFieldService extends AbstractTbEntityService imp
 | 
			
		||||
        return value != null ? value : argument.getDefaultValue();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private <T extends EntityId> void initializeForProfile(TenantId tenantId, List<CalculatedFieldLink> links, CalculatedField cf, Iterable<T> profileIds) {
 | 
			
		||||
        for (T profileId : profileIds) {
 | 
			
		||||
            for (CalculatedFieldLink link : links) {
 | 
			
		||||
                CalculatedFieldLinkConfiguration configuration = link.getConfiguration();
 | 
			
		||||
                initializeStateFromFutures(tenantId, profileId, cf, configuration.getAttributes(), configuration.getTimeSeries());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCalculatedFieldAdded(TransportProtos.CalculatedFieldAddMsgProto proto, TbCallback callback) {
 | 
			
		||||
        try {
 | 
			
		||||
@ -227,33 +232,24 @@ public class DefaultTbCalculatedFieldService extends AbstractTbEntityService imp
 | 
			
		||||
                calculatedFields.put(calculatedFieldId, cf);
 | 
			
		||||
                calculatedFieldLinks.put(calculatedFieldId, links);
 | 
			
		||||
                switch (entityId.getEntityType()) {
 | 
			
		||||
                    case ASSET, DEVICE: {
 | 
			
		||||
                    case ASSET, DEVICE -> {
 | 
			
		||||
                        for (CalculatedFieldLink link : links) {
 | 
			
		||||
                            CalculatedFiledLinkConfiguration configuration = link.getConfiguration();
 | 
			
		||||
                            CalculatedFieldLinkConfiguration configuration = link.getConfiguration();
 | 
			
		||||
                            initializeStateFromFutures(tenantId, link.getEntityId(), cf, configuration.getAttributes(), configuration.getTimeSeries());
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    case ASSET_PROFILE: {
 | 
			
		||||
                    case ASSET_PROFILE -> {
 | 
			
		||||
                        PageDataIterable<AssetId> assetIds = new PageDataIterable<>(pageLink ->
 | 
			
		||||
                                assetService.findAssetIdsByTenantIdAndAssetProfileId(tenantId, (AssetProfileId) entityId, pageLink), initFetchPackSize);
 | 
			
		||||
                        for (AssetId assetId : assetIds) {
 | 
			
		||||
                            for (CalculatedFieldLink link : links) {
 | 
			
		||||
                                CalculatedFiledLinkConfiguration configuration = link.getConfiguration();
 | 
			
		||||
                                initializeStateFromFutures(tenantId, assetId, cf, configuration.getAttributes(), configuration.getTimeSeries());
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        initializeForProfile(tenantId, links, cf, assetIds);
 | 
			
		||||
                    }
 | 
			
		||||
                    case DEVICE_PROFILE: {
 | 
			
		||||
                    case DEVICE_PROFILE -> {
 | 
			
		||||
                        PageDataIterable<DeviceId> deviceIds = new PageDataIterable<>(pageLink ->
 | 
			
		||||
                                deviceService.findDeviceIdsByTenantIdAndDeviceProfileId(tenantId, (DeviceProfileId) entityId, pageLink), initFetchPackSize);
 | 
			
		||||
                        for (DeviceId deviceId : deviceIds) {
 | 
			
		||||
                            for (CalculatedFieldLink link : links) {
 | 
			
		||||
                                CalculatedFiledLinkConfiguration configuration = link.getConfiguration();
 | 
			
		||||
                                initializeStateFromFutures(tenantId, deviceId, cf, configuration.getAttributes(), configuration.getTimeSeries());
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        initializeForProfile(tenantId, links, cf, deviceIds);
 | 
			
		||||
                    }
 | 
			
		||||
                    default: throw new IllegalArgumentException("Entity type '" + calculatedFieldId.getEntityType() + "' does not support calculated fields.");
 | 
			
		||||
                    default ->
 | 
			
		||||
                            throw new IllegalArgumentException("Entity type '" + calculatedFieldId.getEntityType() + "' does not support calculated fields.");
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                //Calculated field or entity was probably deleted while message was in queue;
 | 
			
		||||
@ -336,8 +332,9 @@ public class DefaultTbCalculatedFieldService extends AbstractTbEntityService imp
 | 
			
		||||
 | 
			
		||||
    private void checkEntityExistence(TenantId tenantId, EntityId entityId) {
 | 
			
		||||
        switch (entityId.getEntityType()) {
 | 
			
		||||
            case ASSET, DEVICE, ASSET_PROFILE, DEVICE_PROFILE -> Optional.ofNullable(entityService.fetchEntity(tenantId, entityId))
 | 
			
		||||
                    .orElseThrow(() -> new IllegalArgumentException(entityId.getEntityType().getNormalName() + " with id [" + entityId.getId() + "] does not exist."));
 | 
			
		||||
            case ASSET, DEVICE, ASSET_PROFILE, DEVICE_PROFILE ->
 | 
			
		||||
                    Optional.ofNullable(entityService.fetchEntity(tenantId, entityId))
 | 
			
		||||
                            .orElseThrow(() -> new IllegalArgumentException(entityId.getEntityType().getNormalName() + " with id [" + entityId.getId() + "] does not exist."));
 | 
			
		||||
            default ->
 | 
			
		||||
                    throw new IllegalArgumentException("Entity type '" + entityId.getEntityType() + "' does not support calculated fields.");
 | 
			
		||||
        }
 | 
			
		||||
@ -357,7 +354,8 @@ public class DefaultTbCalculatedFieldService extends AbstractTbEntityService imp
 | 
			
		||||
    private <E extends HasId<I> & HasTenantId, I extends EntityId> E findEntity(TenantId tenantId, EntityId entityId) {
 | 
			
		||||
        return switch (entityId.getEntityType()) {
 | 
			
		||||
            case TENANT, CUSTOMER, ASSET, DEVICE -> (E) entityService.fetchEntity(tenantId, entityId).orElse(null);
 | 
			
		||||
            default -> throw new IllegalArgumentException("Calculated fields do not support entity type '" + entityId.getEntityType() + "' for referenced entities.");
 | 
			
		||||
            default ->
 | 
			
		||||
                    throw new IllegalArgumentException("Calculated fields do not support entity type '" + entityId.getEntityType() + "' for referenced entities.");
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.id.EntityIdFactory;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
@ -37,7 +38,7 @@ public abstract class BaseCalculatedFieldConfiguration implements CalculatedFiel
 | 
			
		||||
    private final ObjectMapper mapper = new ObjectMapper();
 | 
			
		||||
 | 
			
		||||
    protected Map<String, Argument> arguments;
 | 
			
		||||
    protected SimpleCalculatedFieldConfiguration.Output output;
 | 
			
		||||
    protected Output output;
 | 
			
		||||
 | 
			
		||||
    public BaseCalculatedFieldConfiguration() {
 | 
			
		||||
    }
 | 
			
		||||
@ -45,19 +46,20 @@ public abstract class BaseCalculatedFieldConfiguration implements CalculatedFiel
 | 
			
		||||
    public BaseCalculatedFieldConfiguration(JsonNode config, EntityType entityType, UUID entityId) {
 | 
			
		||||
        BaseCalculatedFieldConfiguration calculatedFieldConfig = toCalculatedFieldConfig(config, entityType, entityId);
 | 
			
		||||
        this.arguments = calculatedFieldConfig.getArguments();
 | 
			
		||||
        this.output =  calculatedFieldConfig.getOutput();
 | 
			
		||||
        this.output = calculatedFieldConfig.getOutput();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<EntityId> getReferencedEntities() {
 | 
			
		||||
        return arguments.values().stream()
 | 
			
		||||
                .map(SimpleCalculatedFieldConfiguration.Argument::getEntityId)
 | 
			
		||||
                .map(Argument::getEntityId)
 | 
			
		||||
                .filter(Objects::nonNull)
 | 
			
		||||
                .collect(Collectors.toList());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public CalculatedFiledLinkConfiguration getReferencedEntityConfig(EntityId entityId) {
 | 
			
		||||
        CalculatedFiledLinkConfiguration linkConfiguration = new CalculatedFiledLinkConfiguration();
 | 
			
		||||
    public CalculatedFieldLinkConfiguration getReferencedEntityConfig(EntityId entityId) {
 | 
			
		||||
        CalculatedFieldLinkConfiguration linkConfiguration = new CalculatedFieldLinkConfiguration();
 | 
			
		||||
        arguments.values().stream()
 | 
			
		||||
                .filter(argument -> argument.getEntityId().equals(entityId))
 | 
			
		||||
                .forEach(argument -> {
 | 
			
		||||
 | 
			
		||||
@ -1,43 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2024 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.common.data.cf;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
public class CalculatedFieldConfig {
 | 
			
		||||
 | 
			
		||||
    private Map<String, Argument> arguments;
 | 
			
		||||
    private Output output;
 | 
			
		||||
 | 
			
		||||
    @Data
 | 
			
		||||
    public static class Argument {
 | 
			
		||||
        private EntityId entityId;
 | 
			
		||||
        private String key;
 | 
			
		||||
        private String type;
 | 
			
		||||
        private int defaultValue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Data
 | 
			
		||||
    public static class Output {
 | 
			
		||||
        private String type;
 | 
			
		||||
        private String expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -15,6 +15,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.common.data.cf;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonIgnore;
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
@ -35,14 +36,18 @@ import java.util.UUID;
 | 
			
		||||
})
 | 
			
		||||
public interface CalculatedFieldConfiguration {
 | 
			
		||||
 | 
			
		||||
    @JsonIgnore
 | 
			
		||||
    String getType();
 | 
			
		||||
 | 
			
		||||
    Map<String, BaseCalculatedFieldConfiguration.Argument> getArguments();
 | 
			
		||||
 | 
			
		||||
    @JsonIgnore
 | 
			
		||||
    List<EntityId> getReferencedEntities();
 | 
			
		||||
 | 
			
		||||
    CalculatedFiledLinkConfiguration getReferencedEntityConfig(EntityId entityId);
 | 
			
		||||
    @JsonIgnore
 | 
			
		||||
    CalculatedFieldLinkConfiguration getReferencedEntityConfig(EntityId entityId);
 | 
			
		||||
 | 
			
		||||
    @JsonIgnore
 | 
			
		||||
    JsonNode calculatedFieldConfigToJson(EntityType entityType, UUID entityId);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -37,7 +37,7 @@ public class CalculatedFieldLink extends BaseData<CalculatedFieldLinkId> {
 | 
			
		||||
    @Schema(description = "JSON object with the Calculated Field Id. ", accessMode = Schema.AccessMode.READ_ONLY)
 | 
			
		||||
    private CalculatedFieldId calculatedFieldId;
 | 
			
		||||
    @Schema
 | 
			
		||||
    private transient CalculatedFiledLinkConfiguration configuration;
 | 
			
		||||
    private transient CalculatedFieldLinkConfiguration configuration;
 | 
			
		||||
 | 
			
		||||
    public CalculatedFieldLink() {
 | 
			
		||||
        super();
 | 
			
		||||
@ -47,7 +47,7 @@ public class CalculatedFieldLink extends BaseData<CalculatedFieldLinkId> {
 | 
			
		||||
        super(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public CalculatedFieldLink(TenantId tenantId, EntityId entityId, CalculatedFieldId calculatedFieldId, CalculatedFiledLinkConfiguration configuration) {
 | 
			
		||||
    public CalculatedFieldLink(TenantId tenantId, EntityId entityId, CalculatedFieldId calculatedFieldId, CalculatedFieldLinkConfiguration configuration) {
 | 
			
		||||
        this.tenantId = tenantId;
 | 
			
		||||
        this.entityId = entityId;
 | 
			
		||||
        this.calculatedFieldId = calculatedFieldId;
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
public class CalculatedFiledLinkConfiguration {
 | 
			
		||||
public class CalculatedFieldLinkConfiguration {
 | 
			
		||||
 | 
			
		||||
    private List<String> attributes = new ArrayList<>();
 | 
			
		||||
    private List<String> timeSeries = new ArrayList<>();
 | 
			
		||||
@ -110,13 +110,8 @@ public class BaseCalculatedFieldService implements CalculatedFieldService {
 | 
			
		||||
    @Override
 | 
			
		||||
    public CalculatedFieldLink saveCalculatedFieldLink(TenantId tenantId, CalculatedFieldLink calculatedFieldLink) {
 | 
			
		||||
        calculatedFieldLinkDataValidator.validate(calculatedFieldLink, CalculatedFieldLink::getTenantId);
 | 
			
		||||
        try {
 | 
			
		||||
            log.trace("Executing save calculated field link, [{}]", calculatedFieldLink);
 | 
			
		||||
            return calculatedFieldLinkDao.save(tenantId, calculatedFieldLink);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            checkConstraintViolation(e, "calculated_field_link_unq_key", "Calculated Field for such entity id is already exists!");
 | 
			
		||||
            throw e;
 | 
			
		||||
        }
 | 
			
		||||
        log.trace("Executing save calculated field link, [{}]", calculatedFieldLink);
 | 
			
		||||
        return calculatedFieldLinkDao.save(tenantId, calculatedFieldLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -1,119 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2024 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.dao.cf;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.fasterxml.jackson.databind.node.ObjectNode;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.BaseCalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.SimpleCalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
public class CalculatedFieldConfigUtil {
 | 
			
		||||
 | 
			
		||||
//    public static CalculatedFieldConfiguration toCalculatedFieldConfig(JsonNode config, EntityType entityType, UUID entityId) {
 | 
			
		||||
//        if (config == null) {
 | 
			
		||||
//            return null;
 | 
			
		||||
//        }
 | 
			
		||||
//        try {
 | 
			
		||||
//            CalculatedFieldConfiguration calculatedFieldConfig = new BaseCalculatedFieldConfiguration();
 | 
			
		||||
//            Map<String, Argument> arguments = new HashMap<>();
 | 
			
		||||
//
 | 
			
		||||
//            JsonNode argumentsNode = config.get("arguments");
 | 
			
		||||
//            if (argumentsNode != null && argumentsNode.isObject()) {
 | 
			
		||||
//                argumentsNode.fields().forEachRemaining(entry -> {
 | 
			
		||||
//                    String key = entry.getKey();
 | 
			
		||||
//                    JsonNode argumentNode = entry.getValue();
 | 
			
		||||
//
 | 
			
		||||
//                    CalculatedFieldConfig.Argument argument = new CalculatedFieldConfig.Argument();
 | 
			
		||||
//                    if (argumentNode.has("entityType") && argumentNode.has("entityId")) {
 | 
			
		||||
//                        String referencedEntityType = argumentNode.get("entityType").asText();
 | 
			
		||||
//                        UUID referencedEntityId = UUID.fromString(argumentNode.get("entityId").asText());
 | 
			
		||||
//                        argument.setEntityId(EntityIdFactory.getByTypeAndUuid(referencedEntityType, referencedEntityId));
 | 
			
		||||
//                    } else {
 | 
			
		||||
//                        argument.setEntityId(EntityIdFactory.getByTypeAndUuid(entityType, entityId));
 | 
			
		||||
//                    }
 | 
			
		||||
//                    argument.setKey(argumentNode.get("key").asText());
 | 
			
		||||
//                    argument.setType(argumentNode.get("type").asText());
 | 
			
		||||
//
 | 
			
		||||
//                    if (argumentNode.has("defaultValue")) {
 | 
			
		||||
//                        argument.setDefaultValue(argumentNode.get("defaultValue").asInt());
 | 
			
		||||
//                    }
 | 
			
		||||
//
 | 
			
		||||
//                    arguments.put(key, argument);
 | 
			
		||||
//                });
 | 
			
		||||
//            }
 | 
			
		||||
//            calculatedFieldConfig.setArguments(arguments);
 | 
			
		||||
//
 | 
			
		||||
//            JsonNode outputNode = config.get("output");
 | 
			
		||||
//            if (outputNode != null) {
 | 
			
		||||
//                CalculatedFieldConfig.Output output = new CalculatedFieldConfig.Output();
 | 
			
		||||
//                output.setType(outputNode.get("type").asText());
 | 
			
		||||
//                output.setExpression(outputNode.get("expression").asText());
 | 
			
		||||
//                calculatedFieldConfig.setOutput(output);
 | 
			
		||||
//            }
 | 
			
		||||
//
 | 
			
		||||
//            return calculatedFieldConfig;
 | 
			
		||||
//
 | 
			
		||||
//        } catch (Exception e) {
 | 
			
		||||
//            throw new IllegalArgumentException("Failed to convert JsonNode to CalculatedFieldConfig", e);
 | 
			
		||||
//        }
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    public static JsonNode calculatedFieldConfigToJson(CalculatedFieldConfiguration calculatedFieldConfig, EntityType entityType, UUID entityId) {
 | 
			
		||||
//        if (calculatedFieldConfig == null) {
 | 
			
		||||
//            return null;
 | 
			
		||||
//        }
 | 
			
		||||
//        try {
 | 
			
		||||
//            ObjectNode configNode = JacksonUtil.newObjectNode();
 | 
			
		||||
//
 | 
			
		||||
//            ObjectNode argumentsNode = configNode.putObject("arguments");
 | 
			
		||||
//            calculatedFieldConfig.getArguments().forEach((key, argument) -> {
 | 
			
		||||
//                ObjectNode argumentNode = argumentsNode.putObject(key);
 | 
			
		||||
//                EntityId referencedEntityId = argument.getEntityId();
 | 
			
		||||
//                if (referencedEntityId != null) {
 | 
			
		||||
//                    argumentNode.put("entityType", referencedEntityId.getEntityType().name());
 | 
			
		||||
//                    argumentNode.put("entityId", referencedEntityId.getId().toString());
 | 
			
		||||
//                } else {
 | 
			
		||||
//                    argumentNode.put("entityType", entityType.name());
 | 
			
		||||
//                    argumentNode.put("entityId", entityId.toString());
 | 
			
		||||
//                }
 | 
			
		||||
//                argumentNode.put("key", argument.getKey());
 | 
			
		||||
//                argumentNode.put("type", argument.getType());
 | 
			
		||||
//                argumentNode.put("defaultValue", argument.getDefaultValue());
 | 
			
		||||
//            });
 | 
			
		||||
//
 | 
			
		||||
//            if (calculatedFieldConfig.getOutput() != null) {
 | 
			
		||||
//                ObjectNode outputNode = configNode.putObject("output");
 | 
			
		||||
//                outputNode.put("type", calculatedFieldConfig.getOutput().getType());
 | 
			
		||||
//                outputNode.put("expression", calculatedFieldConfig.getOutput().getExpression());
 | 
			
		||||
//            }
 | 
			
		||||
//
 | 
			
		||||
//            return configNode;
 | 
			
		||||
//
 | 
			
		||||
//        } catch (Exception e) {
 | 
			
		||||
//            throw new IllegalArgumentException("Failed to convert CalculatedFieldConfig to JsonNode", e);
 | 
			
		||||
//        }
 | 
			
		||||
//    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -117,8 +117,7 @@ public class CalculatedFieldEntity extends BaseSqlEntity<CalculatedField> implem
 | 
			
		||||
        return calculatedField;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private  CalculatedFieldConfiguration readCalculatedFieldConfiguration(JsonNode config, EntityType entityType, UUID entityId) {
 | 
			
		||||
        String type = config.get("type").asText();
 | 
			
		||||
    private CalculatedFieldConfiguration readCalculatedFieldConfiguration(JsonNode config, EntityType entityType, UUID entityId) {
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case "SIMPLE":
 | 
			
		||||
                return new SimpleCalculatedFieldConfiguration(config, entityType, entityId);
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@ import lombok.EqualsAndHashCode;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldLink;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFiledLinkConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldLinkConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.id.CalculatedFieldId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.CalculatedFieldLinkId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
 | 
			
		||||
@ -86,7 +86,7 @@ public class CalculatedFieldLinkEntity extends BaseSqlEntity<CalculatedFieldLink
 | 
			
		||||
        calculatedFieldLink.setTenantId(TenantId.fromUUID(tenantId));
 | 
			
		||||
        calculatedFieldLink.setEntityId(EntityIdFactory.getByTypeAndUuid(entityType, entityId));
 | 
			
		||||
        calculatedFieldLink.setCalculatedFieldId(new CalculatedFieldId(calculatedFieldId));
 | 
			
		||||
        calculatedFieldLink.setConfiguration(JacksonUtil.treeToValue(configuration, CalculatedFiledLinkConfiguration.class));
 | 
			
		||||
        calculatedFieldLink.setConfiguration(JacksonUtil.treeToValue(configuration, CalculatedFieldLinkConfiguration.class));
 | 
			
		||||
        return calculatedFieldLink;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldLink;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFiledLinkConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldLinkConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.SimpleCalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.id.CalculatedFieldId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.CalculatedFieldLinkId;
 | 
			
		||||
@ -88,7 +88,7 @@ public class DefaultNativeCalculatedFieldRepository implements NativeCalculatedF
 | 
			
		||||
                calculatedField.setType(type);
 | 
			
		||||
                calculatedField.setName(name);
 | 
			
		||||
                calculatedField.setConfigurationVersion(configurationVersion);
 | 
			
		||||
                calculatedField.setConfiguration(readCalculatedFieldConfiguration(configuration, entityType, entityId));
 | 
			
		||||
                calculatedField.setConfiguration(readCalculatedFieldConfiguration(type, configuration, entityType, entityId));
 | 
			
		||||
                calculatedField.setVersion(version);
 | 
			
		||||
                calculatedField.setExternalId(externalIdObj != null ? new CalculatedFieldId(UUID.fromString((String) externalIdObj)) : null);
 | 
			
		||||
 | 
			
		||||
@ -125,7 +125,7 @@ public class DefaultNativeCalculatedFieldRepository implements NativeCalculatedF
 | 
			
		||||
                calculatedFieldLink.setTenantId(new TenantId(tenantId));
 | 
			
		||||
                calculatedFieldLink.setEntityId(EntityIdFactory.getByTypeAndUuid(entityType, entityId));
 | 
			
		||||
                calculatedFieldLink.setCalculatedFieldId(new CalculatedFieldId(calculatedFieldId));
 | 
			
		||||
                calculatedFieldLink.setConfiguration(JacksonUtil.treeToValue(configuration, CalculatedFiledLinkConfiguration.class));
 | 
			
		||||
                calculatedFieldLink.setConfiguration(JacksonUtil.treeToValue(configuration, CalculatedFieldLinkConfiguration.class));
 | 
			
		||||
 | 
			
		||||
                return calculatedFieldLink;
 | 
			
		||||
            }).collect(Collectors.toList());
 | 
			
		||||
@ -133,8 +133,7 @@ public class DefaultNativeCalculatedFieldRepository implements NativeCalculatedF
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private CalculatedFieldConfiguration readCalculatedFieldConfiguration(JsonNode config, EntityType entityType, UUID entityId) {
 | 
			
		||||
        String type = config.get("type").asText();
 | 
			
		||||
    private CalculatedFieldConfiguration readCalculatedFieldConfiguration(String type, JsonNode config, EntityType entityType, UUID entityId) {
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case "SIMPLE":
 | 
			
		||||
                return new SimpleCalculatedFieldConfiguration(config, entityType, entityId);
 | 
			
		||||
 | 
			
		||||
@ -925,9 +925,7 @@ CREATE TABLE IF NOT EXISTS calculated_field_link (
 | 
			
		||||
    tenant_id uuid NOT NULL,
 | 
			
		||||
    entity_type VARCHAR(32),
 | 
			
		||||
    entity_id uuid NOT NULL,
 | 
			
		||||
--     target_id uuid NOT NULL,
 | 
			
		||||
    calculated_field_id uuid NOT NULL,
 | 
			
		||||
    configuration varchar(1000000),
 | 
			
		||||
    CONSTRAINT calculated_field_link_unq_key UNIQUE (entity_id, calculated_field_id),
 | 
			
		||||
    configuration varchar(10000),
 | 
			
		||||
    CONSTRAINT fk_calculated_field_id FOREIGN KEY (calculated_field_id) REFERENCES calculated_field(id) ON DELETE CASCADE
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.asset.Asset;
 | 
			
		||||
import org.thingsboard.server.common.data.asset.AssetInfo;
 | 
			
		||||
import org.thingsboard.server.common.data.asset.AssetProfile;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.SimpleCalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.id.CustomerId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
@ -874,25 +874,25 @@ public class AssetServiceTest extends AbstractServiceTest {
 | 
			
		||||
        CalculatedField calculatedField = new CalculatedField();
 | 
			
		||||
        calculatedField.setTenantId(tenantId);
 | 
			
		||||
        calculatedField.setName("Test CF");
 | 
			
		||||
        calculatedField.setType("Simple");
 | 
			
		||||
        calculatedField.setType("SIMPLE");
 | 
			
		||||
        calculatedField.setEntityId(savedAssetWithCf.getId());
 | 
			
		||||
 | 
			
		||||
        CalculatedFieldConfig config = new CalculatedFieldConfig();
 | 
			
		||||
        SimpleCalculatedFieldConfiguration config = new SimpleCalculatedFieldConfiguration();
 | 
			
		||||
 | 
			
		||||
        CalculatedFieldConfig.Argument argument = new CalculatedFieldConfig.Argument();
 | 
			
		||||
        SimpleCalculatedFieldConfiguration.Argument argument = new SimpleCalculatedFieldConfiguration.Argument();
 | 
			
		||||
        argument.setEntityId(savedAsset.getId());
 | 
			
		||||
        argument.setType("TIME_SERIES");
 | 
			
		||||
        argument.setKey("temperature");
 | 
			
		||||
 | 
			
		||||
        config.setArguments(Map.of("T", argument));
 | 
			
		||||
 | 
			
		||||
        CalculatedFieldConfig.Output output = new CalculatedFieldConfig.Output();
 | 
			
		||||
        SimpleCalculatedFieldConfiguration.Output output = new SimpleCalculatedFieldConfiguration.Output();
 | 
			
		||||
        output.setType("TIME_SERIES");
 | 
			
		||||
        output.setExpression("T - (100 - H) / 5");
 | 
			
		||||
 | 
			
		||||
        config.setOutput(output);
 | 
			
		||||
 | 
			
		||||
//        calculatedField.setConfiguration(config);
 | 
			
		||||
        calculatedField.setConfiguration(config);
 | 
			
		||||
 | 
			
		||||
        CalculatedField savedCalculatedField = calculatedFieldService.save(calculatedField);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -24,15 +24,17 @@ import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.thingsboard.common.util.ThingsBoardExecutors;
 | 
			
		||||
import org.thingsboard.server.common.data.Device;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldLink;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldLinkConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.SimpleCalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.id.CalculatedFieldId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.DeviceId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
			
		||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
 | 
			
		||||
import org.thingsboard.server.dao.device.DeviceService;
 | 
			
		||||
import org.thingsboard.server.dao.exception.DataValidationException;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@ -128,16 +130,6 @@ public class CalculatedFieldServiceTest extends AbstractServiceTest {
 | 
			
		||||
        assertThat(calculatedFieldService.findById(tenantId, savedCalculatedField.getId())).isNull();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testSaveCalculatedFieldLinkIfCalculatedFieldForSuchEntityExists() {
 | 
			
		||||
        CalculatedField savedCalculatedField = saveValidCalculatedField();
 | 
			
		||||
        CalculatedFieldLink calculatedFieldLink = getCalculatedFieldLink(savedCalculatedField);
 | 
			
		||||
 | 
			
		||||
        assertThatThrownBy(() -> calculatedFieldService.saveCalculatedFieldLink(tenantId, calculatedFieldLink))
 | 
			
		||||
                .isInstanceOf(DataValidationException.class)
 | 
			
		||||
                .hasMessage("Calculated Field for such entity id is already exists!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private CalculatedField saveValidCalculatedField() {
 | 
			
		||||
        Device device = createTestDevice();
 | 
			
		||||
        CalculatedField calculatedField = getCalculatedField(device.getId(), device.getId());
 | 
			
		||||
@ -148,10 +140,10 @@ public class CalculatedFieldServiceTest extends AbstractServiceTest {
 | 
			
		||||
        CalculatedField calculatedField = new CalculatedField();
 | 
			
		||||
        calculatedField.setTenantId(tenantId);
 | 
			
		||||
        calculatedField.setEntityId(entityId);
 | 
			
		||||
        calculatedField.setType("Simple");
 | 
			
		||||
        calculatedField.setType("SIMPLE");
 | 
			
		||||
        calculatedField.setName("Test Calculated Field");
 | 
			
		||||
        calculatedField.setConfigurationVersion(1);
 | 
			
		||||
//        calculatedField.setConfiguration(getCalculatedFieldConfig(referencedEntityId));
 | 
			
		||||
        calculatedField.setConfiguration(getCalculatedFieldConfig(referencedEntityId));
 | 
			
		||||
        calculatedField.setVersion(1L);
 | 
			
		||||
        return calculatedField;
 | 
			
		||||
    }
 | 
			
		||||
@ -160,22 +152,28 @@ public class CalculatedFieldServiceTest extends AbstractServiceTest {
 | 
			
		||||
        CalculatedFieldLink calculatedFieldLink = new CalculatedFieldLink();
 | 
			
		||||
        calculatedFieldLink.setTenantId(tenantId);
 | 
			
		||||
        calculatedFieldLink.setEntityId(calculatedField.getEntityId());
 | 
			
		||||
//        calculatedFieldLink.setConfiguration(calculatedField.getConfiguration());
 | 
			
		||||
        calculatedFieldLink.setConfiguration(getCalculatedFieldLinkConfiguration());
 | 
			
		||||
        calculatedFieldLink.setCalculatedFieldId(calculatedField.getId());
 | 
			
		||||
        return calculatedFieldLink;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private CalculatedFieldConfig getCalculatedFieldConfig(EntityId referencedEntityId) {
 | 
			
		||||
        CalculatedFieldConfig config = new CalculatedFieldConfig();
 | 
			
		||||
    private CalculatedFieldLinkConfiguration getCalculatedFieldLinkConfiguration() {
 | 
			
		||||
        CalculatedFieldLinkConfiguration calculatedFieldLinkConfiguration = new CalculatedFieldLinkConfiguration();
 | 
			
		||||
        calculatedFieldLinkConfiguration.setTimeSeries(List.of("temperature"));
 | 
			
		||||
        return calculatedFieldLinkConfiguration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        CalculatedFieldConfig.Argument argument = new CalculatedFieldConfig.Argument();
 | 
			
		||||
    private CalculatedFieldConfiguration getCalculatedFieldConfig(EntityId referencedEntityId) {
 | 
			
		||||
        SimpleCalculatedFieldConfiguration config = new SimpleCalculatedFieldConfiguration();
 | 
			
		||||
 | 
			
		||||
        SimpleCalculatedFieldConfiguration.Argument argument = new SimpleCalculatedFieldConfiguration.Argument();
 | 
			
		||||
        argument.setEntityId(referencedEntityId);
 | 
			
		||||
        argument.setType("TIME_SERIES");
 | 
			
		||||
        argument.setKey("temperature");
 | 
			
		||||
 | 
			
		||||
        config.setArguments(Map.of("T", argument));
 | 
			
		||||
 | 
			
		||||
        CalculatedFieldConfig.Output output = new CalculatedFieldConfig.Output();
 | 
			
		||||
        SimpleCalculatedFieldConfiguration.Output output = new SimpleCalculatedFieldConfiguration.Output();
 | 
			
		||||
        output.setType("TIME_SERIES");
 | 
			
		||||
        output.setExpression("T - (100 - H) / 5");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.Customer;
 | 
			
		||||
import org.thingsboard.server.common.data.StringUtils;
 | 
			
		||||
import org.thingsboard.server.common.data.asset.Asset;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.SimpleCalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
@ -369,25 +369,25 @@ public class CustomerServiceTest extends AbstractServiceTest {
 | 
			
		||||
        CalculatedField calculatedField = new CalculatedField();
 | 
			
		||||
        calculatedField.setTenantId(tenantId);
 | 
			
		||||
        calculatedField.setName("Test CF");
 | 
			
		||||
        calculatedField.setType("Simple");
 | 
			
		||||
        calculatedField.setType("SIMPLE");
 | 
			
		||||
        calculatedField.setEntityId(savedAsset.getId());
 | 
			
		||||
 | 
			
		||||
        CalculatedFieldConfig config = new CalculatedFieldConfig();
 | 
			
		||||
        SimpleCalculatedFieldConfiguration config = new SimpleCalculatedFieldConfiguration();
 | 
			
		||||
 | 
			
		||||
        CalculatedFieldConfig.Argument argument = new CalculatedFieldConfig.Argument();
 | 
			
		||||
        SimpleCalculatedFieldConfiguration.Argument argument = new SimpleCalculatedFieldConfiguration.Argument();
 | 
			
		||||
        argument.setEntityId(savedCustomer.getId());
 | 
			
		||||
        argument.setType("TIME_SERIES");
 | 
			
		||||
        argument.setKey("temperature");
 | 
			
		||||
 | 
			
		||||
        config.setArguments(Map.of("T", argument));
 | 
			
		||||
 | 
			
		||||
        CalculatedFieldConfig.Output output = new CalculatedFieldConfig.Output();
 | 
			
		||||
        SimpleCalculatedFieldConfiguration.Output output = new SimpleCalculatedFieldConfiguration.Output();
 | 
			
		||||
        output.setType("TIME_SERIES");
 | 
			
		||||
        output.setExpression("T - (100 - H) / 5");
 | 
			
		||||
 | 
			
		||||
        config.setOutput(output);
 | 
			
		||||
 | 
			
		||||
//        calculatedField.setConfiguration(config);
 | 
			
		||||
        calculatedField.setConfiguration(config);
 | 
			
		||||
 | 
			
		||||
        CalculatedField savedCalculatedField = calculatedFieldService.save(calculatedField);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,7 @@ import org.thingsboard.server.common.data.StringUtils;
 | 
			
		||||
import org.thingsboard.server.common.data.Tenant;
 | 
			
		||||
import org.thingsboard.server.common.data.TenantProfile;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedFieldConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.SimpleCalculatedFieldConfiguration;
 | 
			
		||||
import org.thingsboard.server.common.data.id.CustomerId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.OtaPackageId;
 | 
			
		||||
@ -1212,25 +1212,25 @@ public class DeviceServiceTest extends AbstractServiceTest {
 | 
			
		||||
        CalculatedField calculatedField = new CalculatedField();
 | 
			
		||||
        calculatedField.setTenantId(tenantId);
 | 
			
		||||
        calculatedField.setName("Test CF");
 | 
			
		||||
        calculatedField.setType("Simple");
 | 
			
		||||
        calculatedField.setType("SIMPLE");
 | 
			
		||||
        calculatedField.setEntityId(deviceWithCf.getId());
 | 
			
		||||
 | 
			
		||||
        CalculatedFieldConfig config = new CalculatedFieldConfig();
 | 
			
		||||
        SimpleCalculatedFieldConfiguration config = new SimpleCalculatedFieldConfiguration();
 | 
			
		||||
 | 
			
		||||
        CalculatedFieldConfig.Argument argument = new CalculatedFieldConfig.Argument();
 | 
			
		||||
        SimpleCalculatedFieldConfiguration.Argument argument = new SimpleCalculatedFieldConfiguration.Argument();
 | 
			
		||||
        argument.setEntityId(device.getId());
 | 
			
		||||
        argument.setType("TIME_SERIES");
 | 
			
		||||
        argument.setKey("temperature");
 | 
			
		||||
 | 
			
		||||
        config.setArguments(Map.of("T", argument));
 | 
			
		||||
 | 
			
		||||
        CalculatedFieldConfig.Output output = new CalculatedFieldConfig.Output();
 | 
			
		||||
        SimpleCalculatedFieldConfiguration.Output output = new SimpleCalculatedFieldConfiguration.Output();
 | 
			
		||||
        output.setType("TIME_SERIES");
 | 
			
		||||
        output.setExpression("T - (100 - H) / 5");
 | 
			
		||||
 | 
			
		||||
        config.setOutput(output);
 | 
			
		||||
 | 
			
		||||
//        calculatedField.setConfiguration(config);
 | 
			
		||||
        calculatedField.setConfiguration(config);
 | 
			
		||||
 | 
			
		||||
        CalculatedField savedCalculatedField = calculatedFieldService.save(calculatedField);
 | 
			
		||||
 | 
			
		||||
@ -1241,5 +1241,4 @@ public class DeviceServiceTest extends AbstractServiceTest {
 | 
			
		||||
        calculatedFieldService.deleteCalculatedField(tenantId, savedCalculatedField.getId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user