diff --git a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/BusBreakerViolationLocation.java b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/BusBreakerViolationLocation.java index 932a7cb08cf..a06faf79262 100644 --- a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/BusBreakerViolationLocation.java +++ b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/BusBreakerViolationLocation.java @@ -7,47 +7,58 @@ */ package com.powsybl.security; +import com.powsybl.iidm.network.Network; + +import java.util.List; import java.util.Objects; -import java.util.Optional; /** * @author Étienne Lesot {@literal } */ public class BusBreakerViolationLocation implements ViolationLocation { - private final String voltageLevelId; - private final String busId; + private final List busIds; - public BusBreakerViolationLocation(String voltageLevelId, String busId) { - Objects.requireNonNull(voltageLevelId, "voltageLevelId"); - this.voltageLevelId = voltageLevelId; - this.busId = busId; + /** + * Create a ViolationLocation for a violation detected in a voltage level in bus/breaker topology. + * @param busIds The ids of the configured buses (of the bus/breaker view) where the violation was detected. + */ + public BusBreakerViolationLocation(List busIds) { + this.busIds = Objects.requireNonNull(busIds, "busIds should not be null."); } - @Override - public String getVoltageLevelId() { - return voltageLevelId; + /** + * Get the ids of the configured buses (of the bus/breaker view) where the violation was detected. + * @return the configured bus ids + */ + public List getBusIds() { + return busIds; } @Override - public Optional getBusId() { - return Optional.ofNullable(busId); + public Type getType() { + return Type.BUS_BREAKER; } @Override - public String getId() { - return busId == null ? voltageLevelId : busId; + public String toString() { + return "BusBreakerViolationLocation{" + + "busIds='" + busIds + '\'' + + '}'; } @Override - public Type getType() { - return Type.BUS_BREAKER; + public BusView getBusView(Network network) { + return () -> busIds.stream() + .map(id -> network.getBusBreakerView().getBus(id)) + .filter(b -> b.getConnectedTerminalCount() > 0) + .map(b -> b.getConnectedTerminals().iterator().next().getBusView().getBus()) + .distinct(); + } @Override - public String toString() { - return "BusBreakerViolationLocation{" + - "voltageLevelId='" + voltageLevelId + '\'' + - ", busId='" + busId + '\'' + - '}'; + public BusView getBusBreakerView(Network network) { + return () -> busIds.stream().map(id -> network.getBusBreakerView().getBus(id)); } + } diff --git a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/LimitViolationDetection.java b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/LimitViolationDetection.java index 17e389b88f6..44e8ee1c41e 100644 --- a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/LimitViolationDetection.java +++ b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/LimitViolationDetection.java @@ -11,8 +11,11 @@ import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.limitmodification.LimitsComputer; import com.powsybl.iidm.network.util.LimitViolationUtils; +import com.powsybl.iidm.network.util.Networks; import com.powsybl.iidm.network.util.PermanentLimitCheckResult; import com.powsybl.security.detectors.LoadingLimitType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.List; import java.util.Set; @@ -23,6 +26,8 @@ */ public final class LimitViolationDetection { + private static final Logger LOGGER = LoggerFactory.getLogger(LimitViolationDetection.class); + private LimitViolationDetection() { } @@ -206,15 +211,14 @@ private static void checkVoltage(Bus bus, Consumer consumer) { static void checkVoltage(Bus bus, double value, Consumer consumer) { VoltageLevel vl = bus.getVoltageLevel(); - ViolationLocation voltageViolationLocation = createViolationLocation(bus); if (!Double.isNaN(vl.getLowVoltageLimit()) && value <= vl.getLowVoltageLimit()) { consumer.accept(new LimitViolation(vl.getId(), vl.getOptionalName().orElse(null), LimitViolationType.LOW_VOLTAGE, - vl.getLowVoltageLimit(), 1., value, voltageViolationLocation)); + vl.getLowVoltageLimit(), 1., value, createViolationLocation(bus))); } if (!Double.isNaN(vl.getHighVoltageLimit()) && value >= vl.getHighVoltageLimit()) { consumer.accept(new LimitViolation(vl.getId(), vl.getOptionalName().orElse(null), LimitViolationType.HIGH_VOLTAGE, - vl.getHighVoltageLimit(), 1., value, voltageViolationLocation)); + vl.getHighVoltageLimit(), 1., value, createViolationLocation(bus))); } } @@ -268,14 +272,18 @@ static void checkVoltageAngle(VoltageAngleLimit voltageAngleLimit, double value, public static ViolationLocation createViolationLocation(Bus bus) { VoltageLevel vl = bus.getVoltageLevel(); if (vl.getTopologyKind() == TopologyKind.NODE_BREAKER) { - List busbarIds = bus.getConnectedTerminalStream() - .map(Terminal::getConnectable) - .filter(BusbarSection.class::isInstance) - .map(Connectable::getId) - .toList(); - return new NodeBreakerViolationLocation(vl.getId(), busbarIds); + List nodes = Networks.getNodesByBus(vl).get(bus.getId()).stream().toList(); + return new NodeBreakerViolationLocation(vl.getId(), nodes); } else { - return new BusBreakerViolationLocation(vl.getId(), bus.getId()); + try { + List configuredBusIds = vl.getBusBreakerView().getBusStreamFromBusViewBusId(bus.getId()) + .map(Identifiable::getId) + .sorted().toList(); + return new BusBreakerViolationLocation(configuredBusIds); + } catch (Exception e) { + LOGGER.error("Error generating ViolationLocation", e); + return null; + } } } } diff --git a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/NodeBreakerViolationLocation.java b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/NodeBreakerViolationLocation.java index 19386247bdb..2610832fe76 100644 --- a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/NodeBreakerViolationLocation.java +++ b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/NodeBreakerViolationLocation.java @@ -7,6 +7,10 @@ */ package com.powsybl.security; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.VoltageLevel; +import com.powsybl.iidm.network.util.Networks; + import java.util.List; import java.util.Objects; @@ -15,27 +19,43 @@ */ public class NodeBreakerViolationLocation implements ViolationLocation { private final String voltageLevelId; - private final List busBarIds; + private final List nodes; - public NodeBreakerViolationLocation(String voltageLevelId, List busBarIds) { - Objects.requireNonNull(voltageLevelId, "voltageLevelId"); - this.voltageLevelId = voltageLevelId; - this.busBarIds = busBarIds; + /** + * Create a ViolationLocation for a violation detected in a voltage level in node/breaker topology. + * @param voltageLevelId the id of the voltage level + * @param nodes The list of the nodes where the violation was detected. + */ + public NodeBreakerViolationLocation(String voltageLevelId, List nodes) { + this.voltageLevelId = Objects.requireNonNull(voltageLevelId, "voltageLevelId should not be null"); + this.nodes = Objects.requireNonNull(nodes, "nodes should not be null"); } - @Override public String getVoltageLevelId() { return voltageLevelId; } + public List getNodes() { + return nodes; + } + @Override - public List getBusBarIds() { - return busBarIds; + public BusView getBusView(Network network) { + return () -> { + VoltageLevel vl = network.getVoltageLevel(voltageLevelId); + var busView = vl.getBusView(); + return Networks.getNodesByBus(vl) + .entrySet() + .stream() + .filter(e -> nodes.stream().anyMatch(i -> e.getValue().contains(i))) + .map(e -> busView.getBus(e.getKey())) + .distinct(); + }; } @Override - public String getId() { - return busBarIds.isEmpty() ? voltageLevelId : busBarIds.get(0); + public BusView getBusBreakerView(Network network) { + throw new UnsupportedOperationException(); } @Override @@ -47,7 +67,7 @@ public Type getType() { public String toString() { return "NodeBreakerVoltageLocation{" + "voltageLevelId='" + voltageLevelId + '\'' + - ", busBarIds=" + busBarIds + + ", nodes=" + nodes + '}'; } } diff --git a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/ViolationLocation.java b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/ViolationLocation.java index 54e6e5f0798..c5f67caa37a 100644 --- a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/ViolationLocation.java +++ b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/ViolationLocation.java @@ -7,9 +7,10 @@ */ package com.powsybl.security; -import java.util.Collections; -import java.util.List; -import java.util.Optional; +import com.powsybl.iidm.network.Bus; +import com.powsybl.iidm.network.Network; + +import java.util.stream.Stream; /** * @author Étienne Lesot {@literal } @@ -21,18 +22,13 @@ enum Type { BUS_BREAKER } - String getId(); - Type getType(); - String getVoltageLevelId(); + BusView getBusView(Network network); - default Optional getBusId() { - return Optional.empty(); - } + BusView getBusBreakerView(Network network); - default List getBusBarIds() { - return Collections.emptyList(); + interface BusView { + Stream getBusStream(); } - } diff --git a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/detectors/DefaultLimitViolationDetector.java b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/detectors/DefaultLimitViolationDetector.java index 3f6e3ac3609..94b771ab58c 100644 --- a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/detectors/DefaultLimitViolationDetector.java +++ b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/detectors/DefaultLimitViolationDetector.java @@ -78,15 +78,14 @@ public void checkApparentPower(ThreeWindingsTransformer transformer, ThreeSides @Override public void checkVoltage(Bus bus, double value, Consumer consumer) { VoltageLevel vl = bus.getVoltageLevel(); - ViolationLocation voltageViolationLocation = createViolationLocation(bus); if (!Double.isNaN(vl.getLowVoltageLimit()) && value <= vl.getLowVoltageLimit()) { consumer.accept(new LimitViolation(vl.getId(), vl.getOptionalName().orElse(null), LimitViolationType.LOW_VOLTAGE, - vl.getLowVoltageLimit(), limitReductionValue, value, voltageViolationLocation)); + vl.getLowVoltageLimit(), limitReductionValue, value, createViolationLocation(bus))); } if (!Double.isNaN(vl.getHighVoltageLimit()) && value >= vl.getHighVoltageLimit()) { consumer.accept(new LimitViolation(vl.getId(), vl.getOptionalName().orElse(null), LimitViolationType.HIGH_VOLTAGE, - vl.getHighVoltageLimit(), limitReductionValue, value, voltageViolationLocation)); + vl.getHighVoltageLimit(), limitReductionValue, value, createViolationLocation(bus))); } } diff --git a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/json/ViolationLocationDeserializer.java b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/json/ViolationLocationDeserializer.java index 6cb5152dee3..84926326662 100644 --- a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/json/ViolationLocationDeserializer.java +++ b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/json/ViolationLocationDeserializer.java @@ -25,9 +25,9 @@ */ public class ViolationLocationDeserializer extends StdDeserializer { - private static final String BUS_ID = "busId"; + private static final String BUS_IDS = "busIds"; private static final String VOLTAGE_LEVEL_ID = "voltageLevelId"; - private static final String BUS_BAR_IDS = "busbarIds"; + private static final String NODES = "nodes"; public ViolationLocationDeserializer() { super(ViolationLocation.class); @@ -36,8 +36,8 @@ public ViolationLocationDeserializer() { @Override public ViolationLocation deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException { String voltageLevelId = null; - String busId = null; - List busbarIds = new ArrayList<>(); + List busIds = new ArrayList<>(); + List nodes = new ArrayList<>(); ViolationLocation.Type type = null; while (parser.nextToken() != JsonToken.END_OBJECT) { switch (parser.currentName()) { @@ -45,26 +45,27 @@ public ViolationLocation deserialize(JsonParser parser, DeserializationContext d parser.nextToken(); type = JsonUtil.readValue(deserializationContext, parser, ViolationLocation.Type.class); break; - case BUS_ID: - busId = parser.nextTextValue(); + case BUS_IDS: + parser.nextToken(); + busIds = JsonUtil.readList(deserializationContext, parser, String.class); break; case VOLTAGE_LEVEL_ID: voltageLevelId = parser.nextTextValue(); break; - case BUS_BAR_IDS: + case NODES: parser.nextToken(); - busbarIds = JsonUtil.readList(deserializationContext, parser, String.class); + nodes = JsonUtil.readList(deserializationContext, parser, Integer.class); break; default: throw new IllegalStateException("Unexpected field: " + parser.currentName()); } } if (type == ViolationLocation.Type.NODE_BREAKER) { - return new NodeBreakerViolationLocation(voltageLevelId, busbarIds); + return new NodeBreakerViolationLocation(voltageLevelId, nodes); } else if (type == ViolationLocation.Type.BUS_BREAKER) { - return new BusBreakerViolationLocation(voltageLevelId, busId); + return new BusBreakerViolationLocation(busIds); } else { throw new IllegalStateException("type should be among [NODE_BREAKER, BUS_BREAKER]."); } diff --git a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/json/ViolationLocationSerializer.java b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/json/ViolationLocationSerializer.java index 219986b72ee..9d8a7e4b6de 100644 --- a/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/json/ViolationLocationSerializer.java +++ b/security-analysis/security-analysis-api/src/main/java/com/powsybl/security/json/ViolationLocationSerializer.java @@ -11,10 +11,11 @@ import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.powsybl.commons.json.JsonUtil; +import com.powsybl.security.BusBreakerViolationLocation; +import com.powsybl.security.NodeBreakerViolationLocation; import com.powsybl.security.ViolationLocation; import java.io.IOException; -import java.util.Optional; /** * @author Etienne Lesot {@literal } @@ -29,13 +30,13 @@ public ViolationLocationSerializer() { public void serialize(ViolationLocation violationLocation, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeStartObject(); JsonUtil.writeOptionalEnumField(jsonGenerator, "type", violationLocation.getType()); - jsonGenerator.writeStringField("voltageLevelId", violationLocation.getVoltageLevelId()); - Optional busId = violationLocation.getBusId(); - if (busId.isPresent()) { - jsonGenerator.writeStringField("busId", busId.get()); - } - if (!violationLocation.getBusBarIds().isEmpty()) { - serializerProvider.defaultSerializeField("busbarIds", violationLocation.getBusBarIds(), jsonGenerator); + if (ViolationLocation.Type.NODE_BREAKER == violationLocation.getType()) { + NodeBreakerViolationLocation location = (NodeBreakerViolationLocation) violationLocation; + jsonGenerator.writeStringField("voltageLevelId", location.getVoltageLevelId()); + serializerProvider.defaultSerializeField("nodes", location.getNodes(), jsonGenerator); + } else { + BusBreakerViolationLocation location = (BusBreakerViolationLocation) violationLocation; + serializerProvider.defaultSerializeField("busIds", location.getBusIds(), jsonGenerator); } jsonGenerator.writeEndObject(); } diff --git a/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/LimitViolationDetectionTest.java b/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/LimitViolationDetectionTest.java index 8894f659205..cd203e7c214 100644 --- a/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/LimitViolationDetectionTest.java +++ b/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/LimitViolationDetectionTest.java @@ -9,8 +9,8 @@ import com.powsybl.contingency.ContingencyContext; import com.powsybl.iidm.criteria.NetworkElementIdListCriterion; -import com.powsybl.iidm.criteria.duration.PermanentDurationCriterion; import com.powsybl.iidm.criteria.duration.EqualityTemporaryDurationCriterion; +import com.powsybl.iidm.criteria.duration.PermanentDurationCriterion; import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.limitmodification.LimitsComputer; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; @@ -26,8 +26,10 @@ import java.util.*; import java.util.function.Consumer; +import java.util.stream.Collectors; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -104,7 +106,8 @@ protected void checkVoltageAngle(VoltageAngleLimit voltageAngleLimit, double vol @Test void testVoltageViolationDetection() { Network network = EurostagTutorialExample1Factory.createWithFixedCurrentLimits(); - LimitViolationDetection.checkVoltage((Bus) network.getIdentifiable("NHV2"), 620, violationsCollector::add); + Bus mergedBus = getMergedBusFromConfiguredBusId(network, "NHV2"); + LimitViolationDetection.checkVoltage(mergedBus, 620, violationsCollector::add); Assertions.assertThat(violationsCollector) .hasSize(1) .allSatisfy(l -> { @@ -118,7 +121,19 @@ void testVoltageViolationDetection() { @Test void testVoltageViolationDetectionWithDetailLimitViolationId() { Network network = EurostagTutorialExample1Factory.createWithFixedCurrentLimits(); - LimitViolationDetection.checkVoltage((Bus) network.getIdentifiable("NHV2"), 620, violationsCollector::add); + // Add a new bus "NHV20" which will be merged with "NHV2" in the bs view + VoltageLevel vlh2 = network.getVoltageLevel("VLHV2"); + vlh2.getBusBreakerView().newBus() + .setId("NHV20") + .add(); + vlh2.getBusBreakerView().newSwitch() + .setBus1("NHV2").setBus2("NHV20") + .setOpen(false).setId("DJ") + .add(); + // Retrieve the merged bus containing "NHV2" + Bus mergedBus = getMergedBusFromConfiguredBusId(network, "NHV2"); + // Check the voltage on this merged bus + LimitViolationDetection.checkVoltage(mergedBus, 620, violationsCollector::add); Assertions.assertThat(violationsCollector) .hasSize(1) .allSatisfy(l -> { @@ -130,15 +145,24 @@ void testVoltageViolationDetectionWithDetailLimitViolationId() { .get() .isInstanceOfSatisfying(BusBreakerViolationLocation.class, vli -> { - assertEquals("NHV2", vli.getId()); - assertTrue(vli.getBusId().isPresent()); - assertEquals("NHV2", vli.getBusId().get()); - assertEquals("VLHV2", vli.getVoltageLevelId()); - Assertions.assertThat(vli.getBusBarIds()).isEmpty(); + assertEquals(ViolationLocation.Type.BUS_BREAKER, vli.getType()); + assertEquals(2, vli.getBusIds().size()); + assertTrue(vli.getBusIds().containsAll(List.of("NHV2", "NHV20"))); // Both configured buses are present + Set buses = vli.getBusBreakerView(network).getBusStream().collect(Collectors.toSet()); + assertEquals(2, buses.size()); + assertTrue(buses.contains(network.getBusBreakerView().getBus("NHV2"))); + assertTrue(buses.contains(network.getBusBreakerView().getBus("NHV20"))); + Set mergedBuses = vli.getBusView(network).getBusStream().collect(Collectors.toSet()); + assertEquals(1, mergedBuses.size()); }); }); } + private Bus getMergedBusFromConfiguredBusId(Network network, String busId) { + Bus b = (Bus) network.getIdentifiable(busId); + return b.getVoltageLevel().getBusView().getMergedBus(busId); + } + @Test void testVoltageViolationDetectionWithBusBarIds() { Network network = FourSubstationsNodeBreakerFactory.create(); @@ -155,15 +179,30 @@ void testVoltageViolationDetectionWithBusBarIds() { .get() .isInstanceOfSatisfying(NodeBreakerViolationLocation.class, vli -> { - assertEquals("S1VL1_BBS", vli.getId()); - assertTrue(vli.getBusId().isEmpty()); + assertEquals(ViolationLocation.Type.NODE_BREAKER, vli.getType()); assertEquals("S1VL1", vli.getVoltageLevelId()); - Assertions.assertThat(vli.getBusBarIds()) - .hasSize(1) - .first() - .isEqualTo("S1VL1_BBS"); + Assertions.assertThat(vli.getNodes()) + .hasSize(5) + .isEqualTo(List.of(0, 1, 2, 3, 4)); + assertThrows(UnsupportedOperationException.class, () -> vli.getBusBreakerView(network)); + Set mergedBuses = vli.getBusView(network).getBusStream().collect(Collectors.toSet()); + assertEquals(1, mergedBuses.size()); + assertTrue(mergedBuses.contains(network.getBusView().getBus("S1VL1_0"))); }); }); + // Check corresponding busbar sections + ViolationLocation violationLocation = violationsCollector.get(0).getViolationLocation().orElseThrow(); + NodeBreakerViolationLocation vloc = (NodeBreakerViolationLocation) violationLocation; + VoltageLevel vl = network.getVoltageLevel(vloc.getVoltageLevelId()); + List busbarSectionIds = vloc.getNodes().stream() + .map(node -> vl.getNodeBreakerView().getTerminal(node)) + .filter(Objects::nonNull) + .map(Terminal::getConnectable) + .filter(t -> t.getType() == IdentifiableType.BUSBAR_SECTION) + .map(Identifiable::getId) + .toList(); + assertEquals(1, busbarSectionIds.size()); + assertEquals("S1VL1_BBS", busbarSectionIds.get(0)); } @Test diff --git a/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/LimitViolationTest.java b/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/LimitViolationTest.java index 2e7c937cf89..8f4cc2503a4 100644 --- a/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/LimitViolationTest.java +++ b/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/LimitViolationTest.java @@ -87,11 +87,11 @@ void testToString() { LimitViolation limitViolation3 = new LimitViolation("testId", null, LimitViolationType.APPARENT_POWER, null, 6300, 1000, 1, 1100, ThreeSides.THREE); LimitViolation limitViolation4 = new LimitViolation("testId", null, LimitViolationType.LOW_VOLTAGE, - 1000, 1, 1100, new BusBreakerViolationLocation("vlId", "busId")); + 1000, 1, 1100, new BusBreakerViolationLocation(List.of("busId1", "busId2"))); String expected1 = "Subject id: testId, Subject name: null, limitType: HIGH_VOLTAGE, limit: 420.0, limitName: high, acceptableDuration: 2147483647, limitReduction: 1.0, value: 500.0, side: null, voltageLocation: null"; String expected2 = "Subject id: testId, Subject name: null, limitType: CURRENT, limit: 1000.0, limitName: null, acceptableDuration: 6300, limitReduction: 1.0, value: 1100.0, side: ONE, voltageLocation: null"; String expected3 = "Subject id: testId, Subject name: null, limitType: APPARENT_POWER, limit: 1000.0, limitName: null, acceptableDuration: 6300, limitReduction: 1.0, value: 1100.0, side: THREE, voltageLocation: null"; - String expected4 = "Subject id: testId, Subject name: null, limitType: LOW_VOLTAGE, limit: 1000.0, limitName: null, acceptableDuration: 2147483647, limitReduction: 1.0, value: 1100.0, side: null, voltageLocation: BusBreakerViolationLocation{voltageLevelId='vlId', busId='busId'}"; + String expected4 = "Subject id: testId, Subject name: null, limitType: LOW_VOLTAGE, limit: 1000.0, limitName: null, acceptableDuration: 2147483647, limitReduction: 1.0, value: 1100.0, side: null, voltageLocation: BusBreakerViolationLocation{busIds='[busId1, busId2]'}"; assertEquals(expected1, limitViolation1.toString()); assertEquals(expected2, limitViolation2.toString()); assertEquals(expected3, limitViolation3.toString()); diff --git a/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/converter/ExporterTest.java b/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/converter/ExporterTest.java index 90a4a7774c6..d274c92de45 100644 --- a/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/converter/ExporterTest.java +++ b/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/converter/ExporterTest.java @@ -55,8 +55,8 @@ private static SecurityAnalysisResult create() { violation2.addExtension(ActivePowerExtension.class, new ActivePowerExtension(220.0, 230.0)); violation2.addExtension(CurrentExtension.class, new CurrentExtension(95.0)); - LimitViolation violation3 = new LimitViolation("GEN", LimitViolationType.HIGH_VOLTAGE, 100, 0.9f, 110, new BusBreakerViolationLocation("VL", "BUSID")); - LimitViolation violation4 = new LimitViolation("GEN2", LimitViolationType.LOW_VOLTAGE, 100, 0.7f, 115, new NodeBreakerViolationLocation("VL", Arrays.asList("BBS1", "BBS2"))); + LimitViolation violation3 = new LimitViolation("GEN", LimitViolationType.HIGH_VOLTAGE, 100, 0.9f, 110, new BusBreakerViolationLocation(List.of("BUSID"))); + LimitViolation violation4 = new LimitViolation("GEN2", LimitViolationType.LOW_VOLTAGE, 100, 0.7f, 115, new NodeBreakerViolationLocation("VL", Arrays.asList(0, 1))); violation4.addExtension(VoltageExtension.class, new VoltageExtension(400.0)); LimitViolation violation5 = new LimitViolation("NHV1_NHV2_2", LimitViolationType.ACTIVE_POWER, "20'", 1200, 100, 1.0f, 110.0, TwoSides.ONE); diff --git a/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/json/PostContingencyResultTest.java b/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/json/PostContingencyResultTest.java index 8ac679a03af..3f6195f7855 100644 --- a/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/json/PostContingencyResultTest.java +++ b/security-analysis/security-analysis-api/src/test/java/com/powsybl/security/json/PostContingencyResultTest.java @@ -60,9 +60,9 @@ void roundTrip() throws IOException { Contingency contingency = new Contingency("contingency"); LimitViolation violation = new LimitViolation("violation", LimitViolationType.HIGH_VOLTAGE, 420, (float) 0.1, 500); LimitViolation violation2 = new LimitViolation("subject_id", LimitViolationType.HIGH_VOLTAGE, 420, - (float) 0.1, 500, new BusBreakerViolationLocation("vl_id", "bus_id")); + (float) 0.1, 500, new BusBreakerViolationLocation(List.of("bus_id"))); LimitViolation violation3 = new LimitViolation("subject_id", LimitViolationType.LOW_VOLTAGE, 200, - (float) 0.3, 180, new NodeBreakerViolationLocation("vl_id", Collections.singletonList("bbs_id"))); + (float) 0.3, 180, new NodeBreakerViolationLocation("vl_id", Collections.singletonList(0))); LimitViolationsResult result = new LimitViolationsResult(Arrays.asList(violation, violation2, violation3)); List threeWindingsTransformerResults = new ArrayList<>(); threeWindingsTransformerResults.add(new ThreeWindingsTransformerResult("threeWindingsTransformerId", diff --git a/security-analysis/security-analysis-api/src/test/resources/PostContingencyResultTest.json b/security-analysis/security-analysis-api/src/test/resources/PostContingencyResultTest.json index cdda76a6e4a..1e244b657af 100644 --- a/security-analysis/security-analysis-api/src/test/resources/PostContingencyResultTest.json +++ b/security-analysis/security-analysis-api/src/test/resources/PostContingencyResultTest.json @@ -15,8 +15,7 @@ "subjectId" : "subject_id", "violationLocation" : { "type" : "BUS_BREAKER", - "voltageLevelId" : "vl_id", - "busId" : "bus_id" + "busIds" : [ "bus_id" ] }, "limitType" : "HIGH_VOLTAGE", "limit" : 420.0, @@ -27,7 +26,7 @@ "violationLocation" : { "type" : "NODE_BREAKER", "voltageLevelId" : "vl_id", - "busbarIds" : [ "bbs_id" ] + "nodes" : [ 0 ] }, "limitType" : "LOW_VOLTAGE", "limit" : 200.0, diff --git a/security-analysis/security-analysis-api/src/test/resources/SecurityAnalysisResult.json b/security-analysis/security-analysis-api/src/test/resources/SecurityAnalysisResult.json index b6a88c2db22..1d41e66c3b5 100644 --- a/security-analysis/security-analysis-api/src/test/resources/SecurityAnalysisResult.json +++ b/security-analysis/security-analysis-api/src/test/resources/SecurityAnalysisResult.json @@ -105,8 +105,7 @@ "subjectId" : "GEN", "violationLocation" : { "type" : "BUS_BREAKER", - "voltageLevelId" : "VL", - "busId" : "BUSID" + "busIds" : [ "BUSID" ] }, "limitType" : "HIGH_VOLTAGE", "limit" : 100.0, @@ -117,7 +116,7 @@ "violationLocation" : { "type" : "NODE_BREAKER", "voltageLevelId" : "VL", - "busbarIds" : [ "BBS1", "BBS2" ] + "nodes" : [ 0, 1 ] }, "limitType" : "LOW_VOLTAGE", "limit" : 100.0,