diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/alarm/AlarmCalculatedFieldState.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/alarm/AlarmCalculatedFieldState.java index 518121a2d0..b96fde9898 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/alarm/AlarmCalculatedFieldState.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/alarm/AlarmCalculatedFieldState.java @@ -402,28 +402,27 @@ public class AlarmCalculatedFieldState extends BaseCalculatedFieldState { operation = ComplexOperation.AND; } return switch (operation) { - case OR -> { - for (AlarmConditionFilter filter : simpleExpression.getFilters()) { - SingleValueArgumentEntry argument = getArgument(filter.getArgument()); - if (eval(argument, filter.getPredicate())) { - yield true; - } - } - yield false; - } - case AND -> { - for (AlarmConditionFilter filter : simpleExpression.getFilters()) { - SingleValueArgumentEntry argument = getArgument(filter.getArgument()); - if (!eval(argument, filter.getPredicate())) { - yield false; - } - } - yield true; - } + case AND -> simpleExpression.getFilters().stream() + .allMatch(filter -> eval(getArgument(filter.getArgument()), filter)); + case OR -> simpleExpression.getFilters().stream() + .anyMatch(filter -> eval(getArgument(filter.getArgument()), filter)); }; } } + private boolean eval(SingleValueArgumentEntry argument, AlarmConditionFilter filter) { + ComplexOperation operation = filter.getOperation(); + if (operation == null) { + operation = ComplexOperation.AND; + } + return switch (operation) { + case AND -> filter.getPredicates().stream() + .allMatch(predicate -> eval(argument, predicate)); + case OR -> filter.getPredicates().stream() + .anyMatch(predicate -> eval(argument, predicate)); + }; + } + private boolean eval(SingleValueArgumentEntry argument, KeyFilterPredicate predicate) { return switch (predicate.getType()) { case STRING -> evalStrPredicate(argument, (StringFilterPredicate) predicate); diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index 9c285fa9ee..a55832c823 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -461,7 +461,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { BooleanFilterPredicate temperatureAlarmFlagAttributePredicate = new BooleanFilterPredicate(); temperatureAlarmFlagAttributePredicate.setOperation(BooleanFilterPredicate.BooleanOperation.EQUAL); temperatureAlarmFlagAttributePredicate.setValue(new AlarmConditionValue<>(Boolean.TRUE, null)); - temperatureAlarmFlagFilter.setPredicate(temperatureAlarmFlagAttributePredicate); + temperatureAlarmFlagFilter.setPredicates(List.of(temperatureAlarmFlagAttributePredicate)); AlarmConditionFilter temperatureFilter = new AlarmConditionFilter(); temperatureFilter.setArgument("temperature"); @@ -469,7 +469,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { NumericFilterPredicate temperatureFilterPredicate = new NumericFilterPredicate(); temperatureFilterPredicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER); temperatureFilterPredicate.setValue(new AlarmConditionValue<>(null, "temperatureAlarmThreshold")); - temperatureFilter.setPredicate(temperatureFilterPredicate); + temperatureFilter.setPredicates(List.of(temperatureFilterPredicate)); temperatureCondition.setExpression(new SimpleAlarmConditionExpression(List.of(temperatureAlarmFlagFilter, temperatureFilter), ComplexOperation.AND)); temperatureRule.setCondition(temperatureCondition); temperatureRule.setAlarmDetails("Current temperature = ${temperature}"); @@ -486,7 +486,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { NumericFilterPredicate clearTemperatureFilterPredicate = new NumericFilterPredicate(); clearTemperatureFilterPredicate.setOperation(NumericFilterPredicate.NumericOperation.LESS_OR_EQUAL); clearTemperatureFilterPredicate.setValue(new AlarmConditionValue<>(null, "temperatureAlarmThreshold")); - clearTemperatureFilter.setPredicate(clearTemperatureFilterPredicate); + clearTemperatureFilter.setPredicates(List.of(clearTemperatureFilterPredicate)); clearTemperatureCondition.setExpression(new SimpleAlarmConditionExpression(List.of(clearTemperatureFilter), ComplexOperation.AND)); clearTemperatureRule.setCondition(clearTemperatureCondition); clearTemperatureRule.setAlarmDetails("Current temperature = ${temperature}"); @@ -525,7 +525,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { BooleanFilterPredicate humidityAlarmFlagPredicate = new BooleanFilterPredicate(); humidityAlarmFlagPredicate.setOperation(BooleanFilterPredicate.BooleanOperation.EQUAL); humidityAlarmFlagPredicate.setValue(new AlarmConditionValue<>(Boolean.TRUE, null)); - humidityAlarmFlagAttributeFilter.setPredicate(humidityAlarmFlagPredicate); + humidityAlarmFlagAttributeFilter.setPredicates(List.of(humidityAlarmFlagPredicate)); AlarmConditionFilter humidityFilter = new AlarmConditionFilter(); humidityFilter.setArgument("humidity"); @@ -533,7 +533,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { NumericFilterPredicate humidityFilterPredicate = new NumericFilterPredicate(); humidityFilterPredicate.setOperation(NumericFilterPredicate.NumericOperation.LESS); humidityFilterPredicate.setValue(new AlarmConditionValue<>(null, "humidityAlarmThreshold")); - humidityFilter.setPredicate(humidityFilterPredicate); + humidityFilter.setPredicates(List.of(humidityFilterPredicate)); humidityCondition.setExpression(new SimpleAlarmConditionExpression(List.of(humidityAlarmFlagAttributeFilter, humidityFilter), ComplexOperation.AND)); humidityRule.setCondition(humidityCondition); humidityRule.setAlarmDetails("Current humidity = ${humidity}"); @@ -550,7 +550,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { NumericFilterPredicate clearHumidityFilterPredicate = new NumericFilterPredicate(); clearHumidityFilterPredicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER_OR_EQUAL); clearHumidityFilterPredicate.setValue(new AlarmConditionValue<>(null, "humidityAlarmThreshold")); - clearHumidityFilter.setPredicate(clearHumidityFilterPredicate); + clearHumidityFilter.setPredicates(List.of(clearHumidityFilterPredicate)); clearHumidityCondition.setExpression(new SimpleAlarmConditionExpression(List.of(clearHumidityFilter), ComplexOperation.AND)); clearHumidityRule.setCondition(clearHumidityCondition); clearHumidityRule.setAlarmDetails("Current humidity = ${humidity}"); diff --git a/application/src/test/java/org/thingsboard/server/cf/AlarmRulesTest.java b/application/src/test/java/org/thingsboard/server/cf/AlarmRulesTest.java index 652e69781d..b4174e357b 100644 --- a/application/src/test/java/org/thingsboard/server/cf/AlarmRulesTest.java +++ b/application/src/test/java/org/thingsboard/server/cf/AlarmRulesTest.java @@ -174,7 +174,7 @@ public class AlarmRulesTest extends AbstractControllerTest { AlarmConditionValue thresholdValue = new AlarmConditionValue<>(); thresholdValue.setStaticValue(100.0); predicate.setValue(thresholdValue); - filter.setPredicate(predicate); + filter.setPredicates(List.of(predicate)); simpleExpression.setFilters(List.of(filter)); simpleExpression.setOperation(ComplexOperation.AND); Map createRules = Map.of( @@ -860,7 +860,7 @@ public class AlarmRulesTest extends AbstractControllerTest { StringFilterPredicate predicate = new StringFilterPredicate(); predicate.setOperation(stringOperation); predicate.setValue(conditionValue); - filter.setPredicate(predicate); + filter.setPredicates(List.of(predicate)); simpleExpression.setFilters(List.of(filter)); return simpleExpression; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/rule/condition/expression/AlarmConditionFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/rule/condition/expression/AlarmConditionFilter.java index 6a1a36cf35..e99849ea82 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/rule/condition/expression/AlarmConditionFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/rule/condition/expression/AlarmConditionFilter.java @@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.alarm.rule.condition.expression.predic import org.thingsboard.server.common.data.query.EntityKeyValueType; import java.io.Serializable; +import java.util.List; @Data public class AlarmConditionFilter implements Serializable { @@ -31,8 +32,9 @@ public class AlarmConditionFilter implements Serializable { private String argument; @NotNull private EntityKeyValueType valueType; + private ComplexOperation operation; @Valid @NotNull - private KeyFilterPredicate predicate; + private List predicates; }