Skip to content

Commit

Permalink
Merge branch 'main' into calcul-activated-param-sensi
Browse files Browse the repository at this point in the history
  • Loading branch information
ghazwarhili authored Dec 6, 2023
2 parents 8b95765 + 6ddd2ab commit 117f8b9
Show file tree
Hide file tree
Showing 11 changed files with 312 additions and 54 deletions.
13 changes: 13 additions & 0 deletions src/main/java/org/gridsuite/filter/server/FilterController.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.springframework.web.bind.annotation.*;

import jakarta.persistence.EntityNotFoundException;

import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -171,4 +172,16 @@ public ResponseEntity<List<FilterEquipments>> exportFilters(@RequestParam("ids")
.contentType(MediaType.APPLICATION_JSON)
.body(ret);
}

@PostMapping(value = "/filters/evaluate", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Export matched elements to JSON format")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "The list of matched elements")
})
public ResponseEntity<List<IdentifiableAttributes>> evaluateFilter(@RequestParam(value = "networkUuid") UUID networkUuid,
@RequestParam(value = "variantId", required = false) String variantId,
@RequestBody AbstractFilter filter) {
List<IdentifiableAttributes> identifiableAttributes = service.evaluateFilter(filter, networkUuid, variantId);
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(identifiableAttributes);
}
}
5 changes: 5 additions & 0 deletions src/main/java/org/gridsuite/filter/server/FilterService.java
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,11 @@ private List<IdentifiableAttributes> getIdentifiableAttributes(AbstractFilter fi
}
}

public List<IdentifiableAttributes> evaluateFilter(AbstractFilter filter, UUID networkUuid, String variantId) {
Objects.requireNonNull(filter);
return getIdentifiableAttributes(filter, networkUuid, variantId);
}

public Optional<List<IdentifiableAttributes>> exportFilter(UUID id, UUID networkUuid, String variantId) {
Objects.requireNonNull(id);
return getFilter(id).map(filter -> getIdentifiableAttributes(filter, networkUuid, variantId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.Identifiable;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.gridsuite.filter.server.utils.expertfilter.DataType;

Expand All @@ -22,18 +19,8 @@
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
*/
@AllArgsConstructor
@NoArgsConstructor
@Getter
@SuperBuilder
public class EnumExpertRule extends AbstractExpertRule {

@Schema(description = "Value")
private String value;

@Override
public String getStringValue() {
return getValue();
}
public class EnumExpertRule extends StringExpertRule {

@Override
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
Expand All @@ -47,6 +34,8 @@ public boolean evaluateRule(Identifiable<?> identifiable) {
return switch (this.getOperator()) {
case EQUALS -> identifiableValue.equals(this.getValue());
case NOT_EQUALS -> !identifiableValue.equals(this.getValue());
case IN -> this.getValues().contains(identifiableValue);
case NOT_IN -> !this.getValues().contains(identifiableValue);
default -> throw new PowsyblException(this.getOperator() + " operator not supported with " + this.getDataType() + " rule data type");
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package org.gridsuite.filter.server.dto.expertfilter.expertrule;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.Identifiable;
import io.swagger.v3.oas.annotations.media.Schema;
Expand All @@ -16,7 +17,12 @@
import lombok.experimental.SuperBuilder;
import org.gridsuite.filter.server.utils.expertfilter.DataType;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

import static org.gridsuite.filter.server.utils.expertfilter.ExpertFilterUtils.getFieldValue;
import static org.gridsuite.filter.server.utils.expertfilter.OperatorType.isMultipleCriteriaOperator;

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
Expand All @@ -30,6 +36,10 @@ public class NumberExpertRule extends AbstractExpertRule {
@Schema(description = "Value")
private Double value;

@Schema(description = "Values")
@JsonDeserialize(as = HashSet.class)
private Set<Double> values;

public static Double getNumberValue(String value) {
return Double.parseDouble(value);
}
Expand All @@ -54,12 +64,18 @@ public boolean evaluateRule(Identifiable<?> identifiable) {
case LOWER_OR_EQUALS -> identifiableValue.compareTo(filterValue) <= 0;
case LOWER -> identifiableValue.compareTo(filterValue) < 0;
case EXISTS -> true; // We return true here because we already test above if identifiableValue is NaN.
case IN -> this.getValues().contains(identifiableValue);
case NOT_IN -> !this.getValues().contains(identifiableValue);
default -> throw new PowsyblException(this.getOperator() + " operator not supported with " + this.getDataType() + " rule data type");
};
}

@Override
public String getStringValue() {
return String.valueOf(this.getValue());
if (isMultipleCriteriaOperator(this.getOperator())) { // multiple values
return this.getValues().stream().map(String::valueOf).collect(Collectors.joining(","));
} else { // single value or absence
return this.getValue() != null ? String.valueOf(this.getValue()) : null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package org.gridsuite.filter.server.dto.expertfilter.expertrule;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.Identifiable;
import io.swagger.v3.oas.annotations.media.Schema;
Expand All @@ -17,7 +18,11 @@
import org.apache.commons.lang3.StringUtils;
import org.gridsuite.filter.server.utils.expertfilter.DataType;

import java.util.HashSet;
import java.util.Set;

import static org.gridsuite.filter.server.utils.expertfilter.ExpertFilterUtils.getFieldValue;
import static org.gridsuite.filter.server.utils.expertfilter.OperatorType.isMultipleCriteriaOperator;

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
Expand All @@ -31,6 +36,19 @@ public class StringExpertRule extends AbstractExpertRule {
@Schema(description = "Value")
private String value;

@Schema(description = "Values")
@JsonDeserialize(as = HashSet.class)
private Set<String> values;

@Override
public String getStringValue() {
if (isMultipleCriteriaOperator(this.getOperator())) { // multiple values
return String.join(",", this.getValues());
} else { // single value or absence
return this.getValue();
}
}

@Override
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public DataType getDataType() {
Expand All @@ -46,12 +64,9 @@ public boolean evaluateRule(Identifiable<?> identifiable) {
case BEGINS_WITH -> StringUtils.startsWithIgnoreCase(identifiableValue, this.getValue());
case ENDS_WITH -> StringUtils.endsWithIgnoreCase(identifiableValue, this.getValue());
case EXISTS -> !StringUtils.isEmpty(identifiableValue);
case IN -> this.getValues().contains(identifiableValue);
case NOT_IN -> !this.getValues().contains(identifiableValue);
default -> throw new PowsyblException(this.getOperator() + " operator not supported with " + this.getDataType() + " rule data type");
};
}

@Override
public String getStringValue() {
return getValue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
package org.gridsuite.filter.server.repositories.proxies.expertfiler;

import com.powsybl.commons.PowsyblException;
import org.apache.commons.lang3.math.NumberUtils;
import org.gridsuite.filter.server.dto.criteriafilter.AbstractEquipmentFilterForm;
import org.gridsuite.filter.server.dto.AbstractFilter;
import org.gridsuite.filter.server.dto.expertfilter.ExpertFilter;
Expand All @@ -25,6 +24,9 @@
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.gridsuite.filter.server.utils.expertfilter.OperatorType.isMultipleCriteriaOperator;

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
Expand Down Expand Up @@ -67,31 +69,43 @@ public static AbstractExpertRule entityToDto(ExpertRuleEntity filterEntity) {
.build();
}
case NUMBER -> {
Double newValue;
if (NumberUtils.isCreatable(filterEntity.getValue())) {
newValue = NumberUtils.createDouble(filterEntity.getValue());
} else {
newValue = Double.NaN;
}
return NumberExpertRule.builder()
NumberExpertRule.NumberExpertRuleBuilder<?, ?> ruleBuilder = NumberExpertRule.builder()
.field(filterEntity.getField())
.operator(filterEntity.getOperator())
.value(newValue)
.build();
.operator(filterEntity.getOperator());
if (filterEntity.getValue() != null) {
if (isMultipleCriteriaOperator(filterEntity.getOperator())) { // for multiple values
ruleBuilder.values(Stream.of(filterEntity.getValue().split(",")).map(Double::valueOf).collect(Collectors.toSet()));
} else { // for single value
ruleBuilder.value(Double.valueOf(filterEntity.getValue()));
}
}
return ruleBuilder.build();
}
case STRING -> {
return StringExpertRule.builder()
StringExpertRule.StringExpertRuleBuilder<?, ?> ruleBuilder = StringExpertRule.builder()
.field(filterEntity.getField())
.operator(filterEntity.getOperator())
.value(filterEntity.getValue())
.build();
.operator(filterEntity.getOperator());
if (filterEntity.getValue() != null) {
if (isMultipleCriteriaOperator(filterEntity.getOperator())) { // for multiple values
ruleBuilder.values(Stream.of(filterEntity.getValue().split(",")).collect(Collectors.toSet()));
} else { // for single value
ruleBuilder.value(filterEntity.getValue());
}
}
return ruleBuilder.build();
}
case ENUM -> {
return EnumExpertRule.builder()
EnumExpertRule.EnumExpertRuleBuilder<?, ?> ruleBuilder = EnumExpertRule.builder()
.field(filterEntity.getField())
.operator(filterEntity.getOperator())
.value(filterEntity.getValue())
.build();
.operator(filterEntity.getOperator());
if (filterEntity.getValue() != null) {
if (isMultipleCriteriaOperator(filterEntity.getOperator())) { // for multiple values
ruleBuilder.values(Stream.of(filterEntity.getValue().split(",")).collect(Collectors.toSet()));
} else { // for single value
ruleBuilder.value(filterEntity.getValue());
}
}
return ruleBuilder.build();
}
default -> throw new PowsyblException("Unknown rule data type: " + filterEntity.getDataType() + ", supported data types are: COMBINATOR, BOOLEAN, NUMBER, STRING, ENUM");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,28 @@ public static <I extends Identifiable<I>> String getFieldValue(FieldType field,
};
}

private static String getInjectionFieldValue(FieldType field, Injection<?> injection) {
return switch (field) {
case ID -> injection.getId();
case NAME -> injection.getNameOrId();
case COUNTRY -> {
Optional<Country> country = injection.getTerminal().getVoltageLevel().getSubstation().flatMap(Substation::getCountry);
yield country.isPresent() ? String.valueOf(country.get()) : "";
}
case NOMINAL_VOLTAGE -> String.valueOf(injection.getTerminal().getVoltageLevel().getNominalV());
case VOLTAGE_LEVEL_ID -> injection.getTerminal().getVoltageLevel().getId();
default -> throw new PowsyblException("Field " + field + " with " + injection.getType() + " injection type is not implemented with expert filter");
};
}

private static String getLoadFieldValue(FieldType field, Load load) {
return switch (field) {
case ID -> load.getId();
default -> throw new PowsyblException("Field " + field + " with " + load.getType() + " injection type is not implemented with expert filter");
default -> getInjectionFieldValue(field, load);
};
}

private static String getGeneratorFieldValue(FieldType field, Generator generator) {
return switch (field) {
case ID -> generator.getId();
case NAME -> generator.getNameOrId();
case NOMINAL_VOLTAGE -> String.valueOf(generator.getTerminal().getVoltageLevel().getNominalV());
case COUNTRY -> {
Optional<Country> country = generator.getTerminal().getVoltageLevel().getSubstation().flatMap(Substation::getCountry);
yield country.isPresent() ? String.valueOf(country.get()) : "";
}
case ENERGY_SOURCE -> String.valueOf(generator.getEnergySource());
case MIN_P -> String.valueOf(generator.getMinP());
case MAX_P -> String.valueOf(generator.getMaxP());
Expand All @@ -56,6 +62,7 @@ private static String getGeneratorFieldValue(FieldType field, Generator generato
}
yield String.valueOf(Double.NaN);
}
default -> getInjectionFieldValue(field, generator);
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ public enum FieldType {
ENERGY_SOURCE,
COUNTRY,
VOLTAGE_REGULATOR_ON,
PLANNED_ACTIVE_POWER_SET_POINT
PLANNED_ACTIVE_POWER_SET_POINT,
VOLTAGE_LEVEL_ID,
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public enum OperatorType {
// Common
EQUALS,
NOT_EQUALS,
IN,
NOT_IN,
// Number and String
EXISTS,
// Number
Expand All @@ -24,5 +26,9 @@ public enum OperatorType {
IS,
CONTAINS,
BEGINS_WITH,
ENDS_WITH,
ENDS_WITH;

public static boolean isMultipleCriteriaOperator(OperatorType operator) {
return operator == IN || operator == NOT_IN;
}
}
Loading

0 comments on commit 117f8b9

Please sign in to comment.