Skip to content

Commit

Permalink
[Expert Filter] - Support for StaticVarCompensator equipment type (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
thangqp authored Jun 17, 2024
1 parent e214ca3 commit 6c6c3a2
Show file tree
Hide file tree
Showing 10 changed files with 955 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.UUID;

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

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
Expand All @@ -32,11 +33,11 @@
@Setter
@SuperBuilder
public class BooleanExpertRule extends AbstractExpertRule {
private boolean value;
private Boolean value;

@Override
public String getStringValue() {
return String.valueOf(isValue());
return value != null ? value.toString() : null;
}

@Override
Expand All @@ -49,13 +50,15 @@ public DataType getDataType() {
public boolean evaluateRule(Identifiable<?> identifiable, FilterLoader filterLoader, Map<UUID, FilterEquipments> cachedUuidFilters) {
String fieldValue = getFieldValue(this.getField(), null, identifiable);
if (fieldValue == null) {
return false;
return this.getOperator() == NOT_EXISTS;
}
boolean identifiableValue = Boolean.parseBoolean(fieldValue);
boolean filterValue = this.isValue();
Boolean filterValue = this.getValue();
return switch (this.getOperator()) {
case EQUALS -> identifiableValue == filterValue;
case NOT_EQUALS -> identifiableValue != filterValue;
case EXISTS -> identifiableValue;
case NOT_EXISTS -> !identifiableValue;
default -> throw new PowsyblException(this.getOperator() + " operator not supported with " + this.getDataType() + " rule data type");
};
}
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/org/gridsuite/filter/utils/RegulationType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Copyright (c) 2024, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.gridsuite.filter.utils;

/**
* @author Thang PHAM <quyet-thang.pham at rte-france.com>
*/
public enum RegulationType {
LOCAL,
DISTANT
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,18 @@
import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.GeneratorStartup;
import com.powsybl.iidm.network.extensions.StandbyAutomaton;
import org.apache.commons.collections4.CollectionUtils;
import org.gridsuite.filter.FilterLoader;
import org.gridsuite.filter.identifierlistfilter.FilterEquipments;
import org.gridsuite.filter.identifierlistfilter.IdentifiableAttributes;
import org.gridsuite.filter.utils.FilterServiceUtils;
import org.gridsuite.filter.utils.FilterType;
import org.gridsuite.filter.utils.RegulationType;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -51,6 +50,7 @@ public static <I extends Identifiable<I>> String getFieldValue(FieldType field,
case BATTERY -> getBatteryFieldValue(field, propertyName, (Battery) identifiable);
case SUBSTATION -> getSubstationFieldValue(field, (Substation) identifiable);
case TWO_WINDINGS_TRANSFORMER -> getTwoWindingsTransformerFieldValue(field, propertyName, (TwoWindingsTransformer) identifiable);
case STATIC_VAR_COMPENSATOR -> getStaticVarCompensatorFieldValue(field, propertyName, (StaticVarCompensator) identifiable);
default -> throw new PowsyblException(TYPE_NOT_IMPLEMENTED + " [" + identifiable.getType() + "]");
};
};
Expand All @@ -71,6 +71,7 @@ private static String getVoltageLevelFieldValue(FieldType field, String property
case LOW_VOLTAGE_LIMIT -> String.valueOf(voltageLevel.getLowVoltageLimit());
case HIGH_VOLTAGE_LIMIT -> String.valueOf(voltageLevel.getHighVoltageLimit());
case SUBSTATION_PROPERTIES -> voltageLevel.getNullableSubstation().getProperty(propertyName);
case VOLTAGE_LEVEL_PROPERTIES -> voltageLevel.getProperty(propertyName);
default -> throw new PowsyblException(FIELD_AND_TYPE_NOT_IMPLEMENTED + " [" + field + "," + voltageLevel.getType() + "]");
};
}
Expand Down Expand Up @@ -146,7 +147,7 @@ private static String getGeneratorFieldValue(FieldType field, String propertyNam
MARGINAL_COST,
PLANNED_OUTAGE_RATE,
FORCED_OUTAGE_RATE ->
getGeneratorStartupField(generator, field);
getGeneratorStartupFieldValue(generator, field);
case RATED_S -> String.valueOf(generator.getRatedS());
case COUNTRY,
NOMINAL_VOLTAGE,
Expand All @@ -159,9 +160,11 @@ private static String getGeneratorFieldValue(FieldType field, String propertyNam
}

@Nonnull
private static String getGeneratorStartupField(Generator generator, FieldType fieldType) {
private static String getGeneratorStartupFieldValue(Generator generator, FieldType fieldType) {
GeneratorStartup generatorStartup = generator.getExtension(GeneratorStartup.class);
if (generatorStartup != null) {
if (generatorStartup == null) {
return String.valueOf(Double.NaN);
} else {
return String.valueOf(
switch (fieldType) {
case PLANNED_ACTIVE_POWER_SET_POINT -> generatorStartup.getPlannedActivePowerSetpoint();
Expand All @@ -170,8 +173,6 @@ private static String getGeneratorStartupField(Generator generator, FieldType fi
case FORCED_OUTAGE_RATE -> generatorStartup.getForcedOutageRate();
default -> String.valueOf(Double.NaN);
});
} else {
return String.valueOf(Double.NaN);
}
}

Expand All @@ -193,11 +194,20 @@ private static String getBusBarSectionFieldValue(FieldType field, BusbarSection
};
}

private static String getTerminalFieldValue(FieldType field, Terminal terminal) {
private static String getTerminalFieldValue(FieldType field, @Nullable Terminal terminal) {
if (terminal == null) {
return null;
}
return switch (field) {
case CONNECTED,
CONNECTED_1,
CONNECTED_2 -> String.valueOf(terminal.isConnected());
case REGULATING_TERMINAL_VL_ID ->
terminal.getVoltageLevel() != null ?
terminal.getVoltageLevel().getId() : null;
case REGULATING_TERMINAL_CONNECTABLE_ID ->
terminal.getConnectable() != null ?
terminal.getConnectable().getId() : null;
default -> throw new PowsyblException(FIELD_AND_TYPE_NOT_IMPLEMENTED + " [" + field + ",terminal]");
};
}
Expand Down Expand Up @@ -241,7 +251,7 @@ private static String getSubstationFieldValue(FieldType field, Substation substa
};
}

private static String getRatioTapChangerFieldValue(FieldType field, RatioTapChanger ratioTapChanger) {
private static String getRatioTapChangerFieldValue(FieldType field, @Nullable RatioTapChanger ratioTapChanger) {
if (ratioTapChanger == null) {
return null;
}
Expand All @@ -254,7 +264,7 @@ private static String getRatioTapChangerFieldValue(FieldType field, RatioTapChan
};
}

private static String getPhaseTapChangerFieldValue(FieldType field, PhaseTapChanger phaseTapChanger) {
private static String getPhaseTapChangerFieldValue(FieldType field, @Nullable PhaseTapChanger phaseTapChanger) {
if (phaseTapChanger == null) {
return null;
}
Expand Down Expand Up @@ -299,6 +309,67 @@ private static String getTwoWindingsTransformerFieldValue(FieldType field, Strin
};
}

private static String getStaticVarCompensatorFieldValue(FieldType field, String propertyName, StaticVarCompensator svar) {
return switch (field) {
case COUNTRY,
NOMINAL_VOLTAGE,
VOLTAGE_LEVEL_ID,
VOLTAGE_LEVEL_PROPERTIES,
SUBSTATION_PROPERTIES -> getVoltageLevelFieldValue(field, propertyName, svar.getTerminal().getVoltageLevel());
case CONNECTED -> getTerminalFieldValue(field, svar.getTerminal());
case REGULATING_TERMINAL_VL_ID,
REGULATING_TERMINAL_CONNECTABLE_ID -> getTerminalFieldValue(field, svar.getRegulatingTerminal());
case LOW_VOLTAGE_SET_POINT,
HIGH_VOLTAGE_SET_POINT,
LOW_VOLTAGE_THRESHOLD,
HIGH_VOLTAGE_THRESHOLD,
SUSCEPTANCE_FIX,
FIX_Q_AT_NOMINAL_V -> getStandbyAutomatonFieldValue(field, svar);
case REGULATION_TYPE -> svar.getRegulatingTerminal() != null &&
svar.getRegulatingTerminal().getConnectable() != null &&
!Objects.equals(svar.getRegulatingTerminal().getConnectable().getId(), svar.getId()) ?
RegulationType.DISTANT.name() :
RegulationType.LOCAL.name();
case REMOTE_REGULATED_TERMINAL -> svar.getRegulatingTerminal() != null &&
svar.getRegulatingTerminal().getVoltageLevel() != null &&
svar.getRegulatingTerminal().getConnectable() != null &&
!Objects.equals(svar.getRegulatingTerminal().getConnectable().getId(), svar.getId()) ?
String.valueOf(true) : null;
case AUTOMATE -> svar.getExtension(StandbyAutomaton.class) != null ? String.valueOf(true) : null;
case MAX_Q_AT_NOMINAL_V -> String.valueOf(
Math.pow(svar.getTerminal().getVoltageLevel().getNominalV(), 2) * Math.abs(svar.getBmax())
);
case MIN_Q_AT_NOMINAL_V -> String.valueOf(
Math.pow(svar.getTerminal().getVoltageLevel().getNominalV(), 2) * Math.abs(svar.getBmin())
);
case MIN_SUSCEPTANCE -> String.valueOf(svar.getBmin());
case MAX_SUSCEPTANCE -> String.valueOf(svar.getBmax());
case SVAR_REGULATION_MODE -> svar.getRegulationMode() != null ? svar.getRegulationMode().name() : null;
case VOLTAGE_SET_POINT -> String.valueOf(svar.getVoltageSetpoint());
case REACTIVE_POWER_SET_POINT -> String.valueOf(svar.getReactivePowerSetpoint());
default -> throw new PowsyblException(FIELD_AND_TYPE_NOT_IMPLEMENTED + " [" + field + "," + svar.getType() + "]");
};
}

private static String getStandbyAutomatonFieldValue(FieldType field, StaticVarCompensator svar) {
StandbyAutomaton standbyAutomaton = svar.getExtension(StandbyAutomaton.class);
if (standbyAutomaton == null) {
return String.valueOf(Double.NaN);
} else {
return switch (field) {
case LOW_VOLTAGE_SET_POINT -> String.valueOf(standbyAutomaton.getLowVoltageSetpoint());
case HIGH_VOLTAGE_SET_POINT -> String.valueOf(standbyAutomaton.getHighVoltageSetpoint());
case LOW_VOLTAGE_THRESHOLD -> String.valueOf(standbyAutomaton.getLowVoltageThreshold());
case HIGH_VOLTAGE_THRESHOLD -> String.valueOf(standbyAutomaton.getHighVoltageThreshold());
case SUSCEPTANCE_FIX -> String.valueOf(standbyAutomaton.getB0());
case FIX_Q_AT_NOMINAL_V -> String.valueOf(
Math.pow(svar.getTerminal().getVoltageLevel().getNominalV(), 2) * Math.abs(standbyAutomaton.getB0())
);
default -> String.valueOf(Double.NaN);
};
}
}

public static List<FilterEquipments> getFilterEquipments(Network network, Set<String> uuids, FilterLoader filterLoader, Map<UUID, FilterEquipments> cachedUuidFilters) {
List<FilterEquipments> res = new ArrayList<>();
uuids.stream().map(UUID::fromString).forEach(uuid -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ public enum FieldType {
MAXIMUM_SECTION_COUNT,
SHUNT_COMPENSATOR_TYPE,
MAX_Q_AT_NOMINAL_V,
MIN_Q_AT_NOMINAL_V,
FIX_Q_AT_NOMINAL_V,
SWITCHED_ON_Q_AT_NOMINAL_V,
MAX_SUSCEPTANCE,
MIN_SUSCEPTANCE,
SWITCHED_ON_SUSCEPTANCE,
CONNECTED_1,
CONNECTED_2,
Expand Down Expand Up @@ -74,4 +77,17 @@ public enum FieldType {
VOLTAGE_LEVEL_PROPERTIES,
VOLTAGE_LEVEL_PROPERTIES_1,
VOLTAGE_LEVEL_PROPERTIES_2,
SVAR_REGULATION_MODE,
VOLTAGE_SET_POINT,
REACTIVE_POWER_SET_POINT,
REMOTE_REGULATED_TERMINAL, // group criteria of REGULATING_TERMINAL_VL_ID and/or REGULATING_TERMINAL_CONNECTABLE_ID
REGULATING_TERMINAL_VL_ID,
REGULATING_TERMINAL_CONNECTABLE_ID,
REGULATION_TYPE,
AUTOMATE,
LOW_VOLTAGE_SET_POINT,
HIGH_VOLTAGE_SET_POINT,
LOW_VOLTAGE_THRESHOLD,
HIGH_VOLTAGE_THRESHOLD,
SUSCEPTANCE_FIX,
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public enum OperatorType {
NOT_EQUALS,
IN,
NOT_IN,
// Number and String
// Number and String and Boolean
EXISTS,
NOT_EXISTS,
// Number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.StandbyAutomaton;
import org.gridsuite.filter.FilterLoader;
import org.gridsuite.filter.expertfilter.expertrule.BooleanExpertRule;
import org.gridsuite.filter.utils.expertfilter.FieldType;
Expand Down Expand Up @@ -60,6 +61,9 @@ static Stream<Arguments> provideArgumentsForTestWithException() {
BusbarSection busbarSection = Mockito.mock(BusbarSection.class);
Mockito.when(busbarSection.getType()).thenReturn(IdentifiableType.BUSBAR_SECTION);

StaticVarCompensator svar = Mockito.mock(StaticVarCompensator.class);
Mockito.when(svar.getType()).thenReturn(IdentifiableType.STATIC_VAR_COMPENSATOR);

return Stream.of(
// --- Test an unsupported field for each equipment --- //
Arguments.of(EQUALS, FieldType.RATED_S, network, PowsyblException.class),
Expand All @@ -69,6 +73,7 @@ static Stream<Arguments> provideArgumentsForTestWithException() {
Arguments.of(EQUALS, FieldType.RATED_S, shuntCompensator, PowsyblException.class),
Arguments.of(EQUALS, FieldType.RATED_S, bus, PowsyblException.class),
Arguments.of(EQUALS, FieldType.RATED_S, busbarSection, PowsyblException.class),
Arguments.of(EQUALS, FieldType.RATED_S, svar, PowsyblException.class),

// --- Test an unsupported operator for this rule type --- //
Arguments.of(IS, FieldType.VOLTAGE_REGULATOR_ON, generator, PowsyblException.class)
Expand All @@ -82,9 +87,10 @@ static Stream<Arguments> provideArgumentsForTestWithException() {
"provideArgumentsForBatteryTest",
"provideArgumentsForLinesTest",
"provideArgumentsForLoadTest",
"provideArgumentsForTwoWindingTransformerTest"
"provideArgumentsForTwoWindingTransformerTest",
"provideArgumentsForStaticVarCompensatorTest",
})
void testEvaluateRule(OperatorType operator, FieldType field, boolean value, Identifiable<?> equipment, boolean expected) {
void testEvaluateRule(OperatorType operator, FieldType field, Boolean value, Identifiable<?> equipment, boolean expected) {
BooleanExpertRule rule = BooleanExpertRule.builder().operator(operator).field(field).value(value).build();
assertEquals(expected, rule.evaluateRule(equipment, filterLoader, new HashMap<>()));
}
Expand Down Expand Up @@ -296,4 +302,61 @@ private static Stream<Arguments> provideArgumentsForTwoWindingTransformerTest()
Arguments.of(NOT_EQUALS, FieldType.HAS_PHASE_TAP_CHANGER, false, twoWindingsTransformer2, false)
);
}

private static Stream<Arguments> provideArgumentsForStaticVarCompensatorTest() {

StaticVarCompensator svar = Mockito.mock(StaticVarCompensator.class);
Mockito.when(svar.getType()).thenReturn(IdentifiableType.STATIC_VAR_COMPENSATOR);
Mockito.when(svar.getId()).thenReturn("SVAR");
// Terminal fields
Terminal terminal = Mockito.mock(Terminal.class);
Mockito.when(terminal.isConnected()).thenReturn(true);
Mockito.when(svar.getTerminal()).thenReturn(terminal);

// Regulating terminal fields
Terminal regulatingTerminal = Mockito.mock(Terminal.class);
VoltageLevel distantVoltageLevel = Mockito.mock(VoltageLevel.class);
Mockito.when(regulatingTerminal.getVoltageLevel()).thenReturn(distantVoltageLevel);
BusbarSection regulatedBusBarSection = Mockito.mock(BusbarSection.class);
Mockito.when(regulatedBusBarSection.getId()).thenReturn("BBS");
Mockito.when(regulatingTerminal.getConnectable()).thenReturn(regulatedBusBarSection);
Mockito.when(svar.getRegulatingTerminal()).thenReturn(regulatingTerminal);

StandbyAutomaton standbyAutomaton = Mockito.mock(StandbyAutomaton.class);
Mockito.when(svar.getExtension(StandbyAutomaton.class)).thenReturn(standbyAutomaton);

// for testing none EXISTS automaton and regulating terminal
StaticVarCompensator svar1 = Mockito.mock(StaticVarCompensator.class);
Mockito.when(svar1.getType()).thenReturn(IdentifiableType.STATIC_VAR_COMPENSATOR);

// configure a regulating terminal without connected equipment
Terminal regulatingTerminal1 = Mockito.mock(Terminal.class);
VoltageLevel distantVoltageLevel1 = Mockito.mock(VoltageLevel.class);
Mockito.when(regulatingTerminal1.getVoltageLevel()).thenReturn(distantVoltageLevel1);
Mockito.when(svar1.getRegulatingTerminal()).thenReturn(regulatingTerminal1);

return Stream.of(
// --- EQUALS--- //
// Terminal fields
Arguments.of(EQUALS, FieldType.CONNECTED, true, svar, true),
Arguments.of(EQUALS, FieldType.CONNECTED, false, svar, false),

// --- NOT_EQUALS--- //
// Terminal fields
Arguments.of(NOT_EQUALS, FieldType.CONNECTED, false, svar, true),
Arguments.of(NOT_EQUALS, FieldType.CONNECTED, true, svar, false),

// --- EXISTS--- //
Arguments.of(EXISTS, FieldType.REMOTE_REGULATED_TERMINAL, null, svar, true),
Arguments.of(EXISTS, FieldType.REMOTE_REGULATED_TERMINAL, null, svar1, false),
Arguments.of(EXISTS, FieldType.AUTOMATE, null, svar, true),
Arguments.of(EXISTS, FieldType.AUTOMATE, null, svar1, false),

// --- NOT_EXISTS--- //
Arguments.of(NOT_EXISTS, FieldType.REMOTE_REGULATED_TERMINAL, null, svar, false),
Arguments.of(NOT_EXISTS, FieldType.REMOTE_REGULATED_TERMINAL, null, svar1, true),
Arguments.of(NOT_EXISTS, FieldType.AUTOMATE, null, svar, false),
Arguments.of(NOT_EXISTS, FieldType.AUTOMATE, null, svar1, true)
);
}
}
Loading

0 comments on commit 6c6c3a2

Please sign in to comment.