diff --git a/data/crac/crac-io/crac-io-cim/src/main/java/com/powsybl/openrao/data/crac/io/cim/craccreator/HvdcRangeActionCreator.java b/data/crac/crac-io/crac-io-cim/src/main/java/com/powsybl/openrao/data/crac/io/cim/craccreator/HvdcRangeActionCreator.java index 46bda87c14..e71c680ed3 100644 --- a/data/crac/crac-io/crac-io-cim/src/main/java/com/powsybl/openrao/data/crac/io/cim/craccreator/HvdcRangeActionCreator.java +++ b/data/crac/crac-io/crac-io-cim/src/main/java/com/powsybl/openrao/data/crac/io/cim/craccreator/HvdcRangeActionCreator.java @@ -62,7 +62,7 @@ public HvdcRangeActionCreator(Crac crac, Network network, List cont this.cimCracCreationParameters = cimCracCreationParameters; } - public void addDirection(RemedialActionSeries remedialActionSeries) { + public void addDirection(RemedialActionSeries remedialActionSeries, String applicationModeMarketObjectStatus) { raSeriesIds.add(remedialActionSeries.getMRID()); try { @@ -87,7 +87,7 @@ public void addDirection(RemedialActionSeries remedialActionSeries) { } networkElementIds.add(networkElementId); - checkHvdcNetworkElementAndInitAdder(registeredResource, networkElementId); + checkHvdcNetworkElementAndInitAdder(registeredResource, networkElementId, applicationModeMarketObjectStatus); isRemedialActionSeriesInverted = readRangeAndCheckIfInverted(isRemedialActionSeriesInverted, registeredResource, networkElementId); } @@ -117,14 +117,14 @@ private Boolean readRangeAndCheckIfInverted(Boolean isRemedialActionSeriesInvert } } - private void checkHvdcNetworkElementAndInitAdder(RemedialActionRegisteredResource registeredResource, String networkElementId) { + private void checkHvdcNetworkElementAndInitAdder(RemedialActionRegisteredResource registeredResource, String networkElementId, String applicationModeMarketObjectStatus) { checkHvdcNetworkElement(networkElementId); HvdcLine hvdcLine = network.getHvdcLine(networkElementId); boolean terminal1Connected = hvdcLine.getConverterStation1().getTerminal().isConnected(); boolean terminal2Connected = hvdcLine.getConverterStation2().getTerminal().isConnected(); if (terminal1Connected && terminal2Connected) { - hvdcRangeActionAdders.putIfAbsent(networkElementId, initHvdcRangeActionAdder(registeredResource)); + hvdcRangeActionAdders.putIfAbsent(networkElementId, initHvdcRangeActionAdder(registeredResource, applicationModeMarketObjectStatus)); } else { isAltered = true; importStatusDetailifIsAltered = String.format("HVDC line %s has ", hvdcLine.getId()); @@ -197,7 +197,7 @@ public Set add() { return raSeriesIds.stream().map(id -> RemedialActionSeriesCreationContext.importedHvdcRa(id, createdRaIds, isAltered, isDirectionInverted.get(id), importStatusDetailifIsAltered)).collect(Collectors.toSet()); } - private HvdcRangeActionAdder initHvdcRangeActionAdder(RemedialActionRegisteredResource registeredResource) { + private HvdcRangeActionAdder initHvdcRangeActionAdder(RemedialActionRegisteredResource registeredResource, String applicationModeMarketObjectStatus) { HvdcRangeActionAdder hvdcRangeActionAdder = crac.newHvdcRangeAction(); String hvdcId = registeredResource.getMRID().getValue(); hvdcRangeActionAdder.withNetworkElement(hvdcId); @@ -215,7 +215,7 @@ private HvdcRangeActionAdder initHvdcRangeActionAdder(RemedialActionRegisteredRe } // Usage rules - RemedialActionSeriesCreator.addUsageRules(crac, CimConstants.ApplicationModeMarketObjectStatus.AUTO.getStatus(), hvdcRangeActionAdder, contingencies, invalidContingencies, cnecs, sharedDomain); + RemedialActionSeriesCreator.addUsageRules(crac, applicationModeMarketObjectStatus, hvdcRangeActionAdder, contingencies, invalidContingencies, cnecs, sharedDomain); return hvdcRangeActionAdder; } diff --git a/data/crac/crac-io/crac-io-cim/src/main/java/com/powsybl/openrao/data/crac/io/cim/craccreator/RemedialActionSeriesCreator.java b/data/crac/crac-io/crac-io-cim/src/main/java/com/powsybl/openrao/data/crac/io/cim/craccreator/RemedialActionSeriesCreator.java index 5e2e283898..203735b59d 100644 --- a/data/crac/crac-io/crac-io-cim/src/main/java/com/powsybl/openrao/data/crac/io/cim/craccreator/RemedialActionSeriesCreator.java +++ b/data/crac/crac-io/crac-io-cim/src/main/java/com/powsybl/openrao/data/crac/io/cim/craccreator/RemedialActionSeriesCreator.java @@ -315,16 +315,12 @@ private boolean identifyAndReadHvdcRangeAction(RemedialActionSeries remedialActi String applicationModeMarketObjectStatus = remedialActionSeries.getApplicationModeMarketObjectStatusStatus(); for (RemedialActionRegisteredResource remedialActionRegisteredResource : remedialActionRegisteredResources) { if (remedialActionRegisteredResource.getPSRTypePsrType().equals(PsrType.HVDC.getStatus())) { - if (!applicationModeMarketObjectStatus.equals(ApplicationModeMarketObjectStatus.AUTO.getStatus())) { - remedialActionSeriesCreationContexts.add(RemedialActionSeriesCreationContext.notImported(remedialActionSeries.getMRID(), ImportStatus.INCONSISTENCY_IN_DATA, String.format("HVDC cannot be imported at instant %s", applicationModeMarketObjectStatus))); - return true; - } if (Objects.isNull(hvdcRangeActionCreator)) { hvdcRangeActionCreator = new HvdcRangeActionCreator( crac, network, contingencies, invalidContingencies, cnecs, sharedDomain, cimCracCreationParameters); } - hvdcRangeActionCreator.addDirection(remedialActionSeries); + hvdcRangeActionCreator.addDirection(remedialActionSeries, applicationModeMarketObjectStatus); return true; } } diff --git a/data/crac/crac-io/crac-io-cim/src/test/java/com/powsybl/openrao/data/crac/io/cim/craccreator/CimCracCreatorTest.java b/data/crac/crac-io/crac-io-cim/src/test/java/com/powsybl/openrao/data/crac/io/cim/craccreator/CimCracCreatorTest.java index 5302d1124a..519b638d91 100644 --- a/data/crac/crac-io/crac-io-cim/src/test/java/com/powsybl/openrao/data/crac/io/cim/craccreator/CimCracCreatorTest.java +++ b/data/crac/crac-io/crac-io-cim/src/test/java/com/powsybl/openrao/data/crac/io/cim/craccreator/CimCracCreatorTest.java @@ -30,6 +30,7 @@ import com.powsybl.openrao.data.crac.api.usagerule.OnContingencyState; import com.powsybl.openrao.data.crac.api.usagerule.OnFlowConstraintInCountry; import com.powsybl.openrao.data.crac.api.usagerule.OnInstant; +import com.powsybl.openrao.data.crac.api.usagerule.UsageRule; import com.powsybl.openrao.data.crac.io.cim.parameters.CimCracCreationParameters; import com.powsybl.openrao.data.crac.io.cim.parameters.RangeActionSpeed; import com.powsybl.openrao.data.crac.io.cim.parameters.VoltageCnecsCreationParameters; @@ -1237,4 +1238,83 @@ void testImportHvdcAutomatonWithPartiallyConnectedHvdc2AndInvalidContingencies() assert cracCreationContext.getCreationReport().getReport().contains("[ALTERED] RemedialAction_Series \"HVDC-direction12\" was modified: HVDC line BBE2AA12 FFR3AA12 1 has terminals 1 and 2 disconnected; Contingencies Co-2 were not imported. "); assert cracCreationContext.getCreationReport().getReport().contains("[ALTERED] RemedialAction_Series \"HVDC-direction11\" was modified: HVDC line BBE2AA12 FFR3AA12 1 has terminals 1 and 2 disconnected; Contingencies Co-2 were not imported. "); } + + @Test + void importCimCracWithPreventiveHvdcRa() throws IOException { + Network network = loadNetworkWithHvdc(); + setUpWithSpeed("/cracs/CIM_with_preventive_HVDC.xml", network, OffsetDateTime.parse("2021-04-01T23:00Z"), Set.of(new RangeActionSpeed("BBE2AA11 FFR3AA11 1", 1), new RangeActionSpeed("BBE2AA12 FFR3AA12 1", 2))); + Crac crac = cracCreationContext.getCrac(); + + assertEquals(2, crac.getHvdcRangeActions().size()); + + HvdcRangeAction hvdcRangeAction1 = crac.getHvdcRangeAction("HVDC-direction11 + HVDC-direction12 - BBE2AA11 FFR3AA11 1"); + assertEquals(1, hvdcRangeAction1.getRanges().size()); + assertEquals(-4000, hvdcRangeAction1.getRanges().iterator().next().getMin()); + assertEquals(5000, hvdcRangeAction1.getRanges().iterator().next().getMax()); + assertEquals(Optional.of("BBE2AA11 FFR3AA11 1 + BBE2AA12 FFR3AA12 1"), hvdcRangeAction1.getGroupId()); + assertEquals(1, hvdcRangeAction1.getUsageRules().size()); + assertEquals("preventive", hvdcRangeAction1.getUsageRules().iterator().next().getInstant().getId()); + + HvdcRangeAction hvdcRangeAction2 = crac.getHvdcRangeAction("HVDC-direction11 + HVDC-direction12 - BBE2AA12 FFR3AA12 1"); + assertEquals(1, hvdcRangeAction2.getRanges().size()); + assertEquals(-3000, hvdcRangeAction2.getRanges().iterator().next().getMin()); + assertEquals(3500, hvdcRangeAction2.getRanges().iterator().next().getMax()); + assertEquals(Optional.of("BBE2AA11 FFR3AA11 1 + BBE2AA12 FFR3AA12 1"), hvdcRangeAction2.getGroupId()); + assertEquals(1, hvdcRangeAction2.getUsageRules().size()); + assertEquals("preventive", hvdcRangeAction2.getUsageRules().iterator().next().getInstant().getId()); + } + + @Test + void importCimCracWithCurativeHvdcRa() throws IOException { + Network network = loadNetworkWithHvdc(); + setUpWithSpeed("/cracs/CIM_with_curative_HVDC.xml", network, OffsetDateTime.parse("2021-04-01T23:00Z"), Set.of(new RangeActionSpeed("BBE2AA11 FFR3AA11 1", 1), new RangeActionSpeed("BBE2AA12 FFR3AA12 1", 2))); + Crac crac = cracCreationContext.getCrac(); + + assertEquals(2, crac.getHvdcRangeActions().size()); + + HvdcRangeAction hvdcRangeAction1 = crac.getHvdcRangeAction("HVDC-direction11 + HVDC-direction12 - BBE2AA11 FFR3AA11 1"); + assertEquals(1, hvdcRangeAction1.getRanges().size()); + assertEquals(-4000, hvdcRangeAction1.getRanges().iterator().next().getMin()); + assertEquals(5000, hvdcRangeAction1.getRanges().iterator().next().getMax()); + assertEquals(Optional.of("BBE2AA11 FFR3AA11 1 + BBE2AA12 FFR3AA12 1"), hvdcRangeAction1.getGroupId()); + assertEquals(1, hvdcRangeAction1.getUsageRules().size()); + assertEquals("curative", hvdcRangeAction1.getUsageRules().iterator().next().getInstant().getId()); + + HvdcRangeAction hvdcRangeAction2 = crac.getHvdcRangeAction("HVDC-direction11 + HVDC-direction12 - BBE2AA12 FFR3AA12 1"); + assertEquals(1, hvdcRangeAction2.getRanges().size()); + assertEquals(-3000, hvdcRangeAction2.getRanges().iterator().next().getMin()); + assertEquals(3500, hvdcRangeAction2.getRanges().iterator().next().getMax()); + assertEquals(Optional.of("BBE2AA11 FFR3AA11 1 + BBE2AA12 FFR3AA12 1"), hvdcRangeAction2.getGroupId()); + assertEquals(1, hvdcRangeAction2.getUsageRules().size()); + assertEquals("curative", hvdcRangeAction2.getUsageRules().iterator().next().getInstant().getId()); + } + + @Test + void importCimCracWithPreventiveAndCurativeHvdcRa() throws IOException { + Network network = loadNetworkWithHvdc(); + setUpWithSpeed("/cracs/CIM_with_preventive_and_curative_HVDC.xml", network, OffsetDateTime.parse("2021-04-01T23:00Z"), Set.of(new RangeActionSpeed("BBE2AA11 FFR3AA11 1", 1), new RangeActionSpeed("BBE2AA12 FFR3AA12 1", 2))); + Crac crac = cracCreationContext.getCrac(); + + assertEquals(2, crac.getHvdcRangeActions().size()); + + HvdcRangeAction hvdcRangeAction1 = crac.getHvdcRangeAction("HVDC-direction11 + HVDC-direction12 - BBE2AA11 FFR3AA11 1"); + assertEquals(1, hvdcRangeAction1.getRanges().size()); + assertEquals(-4000, hvdcRangeAction1.getRanges().iterator().next().getMin()); + assertEquals(5000, hvdcRangeAction1.getRanges().iterator().next().getMax()); + assertEquals(Optional.of("BBE2AA11 FFR3AA11 1 + BBE2AA12 FFR3AA12 1"), hvdcRangeAction1.getGroupId()); + List usageRules1 = hvdcRangeAction1.getUsageRules().stream().sorted(Comparator.comparing(ur -> ur.getInstant().getId())).toList(); + assertEquals(2, usageRules1.size()); + assertEquals("curative", usageRules1.getFirst().getInstant().getId()); + assertEquals("preventive", usageRules1.getLast().getInstant().getId()); + + HvdcRangeAction hvdcRangeAction2 = crac.getHvdcRangeAction("HVDC-direction11 + HVDC-direction12 - BBE2AA12 FFR3AA12 1"); + assertEquals(1, hvdcRangeAction2.getRanges().size()); + assertEquals(-3000, hvdcRangeAction2.getRanges().iterator().next().getMin()); + assertEquals(3500, hvdcRangeAction2.getRanges().iterator().next().getMax()); + assertEquals(Optional.of("BBE2AA11 FFR3AA11 1 + BBE2AA12 FFR3AA12 1"), hvdcRangeAction2.getGroupId()); + List usageRules2 = hvdcRangeAction2.getUsageRules().stream().sorted(Comparator.comparing(ur -> ur.getInstant().getId())).toList(); + assertEquals(2, usageRules2.size()); + assertEquals("curative", usageRules2.getFirst().getInstant().getId()); + assertEquals("preventive", usageRules2.getLast().getInstant().getId()); + } } diff --git a/data/crac/crac-io/crac-io-cim/src/test/resources/cracs/CIM_with_curative_HVDC.xml b/data/crac/crac-io/crac-io-cim/src/test/resources/cracs/CIM_with_curative_HVDC.xml new file mode 100644 index 0000000000..0619234e79 --- /dev/null +++ b/data/crac/crac-io/crac-io-cim/src/test/resources/cracs/CIM_with_curative_HVDC.xml @@ -0,0 +1,161 @@ + + + CIM_CRAC_DOCUMENT + 1 + B15 + A48 + FAKE + A36 + FAKE + A04 + 2021-03-31T15:02:00Z + + A42 + + + 2021-04-01T22:00Z + 2021-04-02T22:00Z + + 10YCB-FR-ES-PT-S + + TimeSeries + B54 + A03 + 1------0 + 1------0 + + + 2021-04-01T22:00Z + 2021-04-02T22:00Z + + PT60M + + 2 + + Contingencies_1 + B55 + Contingencies_1 + A52 + + Co-1 + Contingency name + + FFR1AA11 FFR3AA11 1 + FFR1AA11 FFR3AA11 1 + 10YFR-RTE------C + 10YFR-RTE------C + + + + + RA-Series-1 + B56 + HVDC valid range actions + A52 + + HVDC-direction11 + HVDC-direction11-ra + B59 + A19 + A39 + + BBE2AA11 FFR3AA11 1 + PMode on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + A43 + + + BBE2AA11 FFR3AA11 1 + RangeAction on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + FFR3AA1 + BBE2AA1 + A26 + 5000.0 + 0 + 500.0 + MAW + + + BBE2AA12 FFR3AA12 1 + PMode on HVDC BE2 FR3 2 + B22 + 1------C + 1------C2 + A43 + + + BBE2AA12 FFR3AA12 1 + RangeAction on HVDC BE2 FR3 2 + B22 + 1------C + 1------C + FFR3AA1 + BBE2AA1 + A26 + 3500.0 + 0 + 500.0 + MAW + + + + HVDC-direction12 + HVDC-direction12-ra + B59 + A19 + A39 + + BBE2AA11 FFR3AA11 1 + PMode on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + A43 + + + BBE2AA11 FFR3AA11 1 + RangeAction on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + BBE2AA1 + FFR3AA1 + A26 + 4000.0 + 0 + 500.0 + MAW + + + BBE2AA12 FFR3AA12 1 + PMode on HVDC BE2 FR3 2 + B22 + 1------C + 1------C + A43 + + + BBE2AA12 FFR3AA12 1 + RangeAction on HVDC BE2 FR3 2 + B22 + 1------C + 1------C + BBE2AA1 + FFR3AA1 + A26 + 3000.0 + 0 + 500.0 + MAW + + + + + + + \ No newline at end of file diff --git a/data/crac/crac-io/crac-io-cim/src/test/resources/cracs/CIM_with_preventive_HVDC.xml b/data/crac/crac-io/crac-io-cim/src/test/resources/cracs/CIM_with_preventive_HVDC.xml new file mode 100644 index 0000000000..5aac81e439 --- /dev/null +++ b/data/crac/crac-io/crac-io-cim/src/test/resources/cracs/CIM_with_preventive_HVDC.xml @@ -0,0 +1,161 @@ + + + CIM_CRAC_DOCUMENT + 1 + B15 + A48 + FAKE + A36 + FAKE + A04 + 2021-03-31T15:02:00Z + + A42 + + + 2021-04-01T22:00Z + 2021-04-02T22:00Z + + 10YCB-FR-ES-PT-S + + TimeSeries + B54 + A03 + 1------0 + 1------0 + + + 2021-04-01T22:00Z + 2021-04-02T22:00Z + + PT60M + + 2 + + Contingencies_1 + B55 + Contingencies_1 + A52 + + Co-1 + Contingency name + + FFR1AA11 FFR3AA11 1 + FFR1AA11 FFR3AA11 1 + 10YFR-RTE------C + 10YFR-RTE------C + + + + + RA-Series-1 + B56 + HVDC valid range actions + A52 + + HVDC-direction11 + HVDC-direction11-ra + B59 + A18 + A39 + + BBE2AA11 FFR3AA11 1 + PMode on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + A43 + + + BBE2AA11 FFR3AA11 1 + RangeAction on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + FFR3AA1 + BBE2AA1 + A26 + 5000.0 + 0 + 500.0 + MAW + + + BBE2AA12 FFR3AA12 1 + PMode on HVDC BE2 FR3 2 + B22 + 1------C + 1------C2 + A43 + + + BBE2AA12 FFR3AA12 1 + RangeAction on HVDC BE2 FR3 2 + B22 + 1------C + 1------C + FFR3AA1 + BBE2AA1 + A26 + 3500.0 + 0 + 500.0 + MAW + + + + HVDC-direction12 + HVDC-direction12-ra + B59 + A18 + A39 + + BBE2AA11 FFR3AA11 1 + PMode on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + A43 + + + BBE2AA11 FFR3AA11 1 + RangeAction on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + BBE2AA1 + FFR3AA1 + A26 + 4000.0 + 0 + 500.0 + MAW + + + BBE2AA12 FFR3AA12 1 + PMode on HVDC BE2 FR3 2 + B22 + 1------C + 1------C + A43 + + + BBE2AA12 FFR3AA12 1 + RangeAction on HVDC BE2 FR3 2 + B22 + 1------C + 1------C + BBE2AA1 + FFR3AA1 + A26 + 3000.0 + 0 + 500.0 + MAW + + + + + + + \ No newline at end of file diff --git a/data/crac/crac-io/crac-io-cim/src/test/resources/cracs/CIM_with_preventive_and_curative_HVDC.xml b/data/crac/crac-io/crac-io-cim/src/test/resources/cracs/CIM_with_preventive_and_curative_HVDC.xml new file mode 100644 index 0000000000..136bc4132d --- /dev/null +++ b/data/crac/crac-io/crac-io-cim/src/test/resources/cracs/CIM_with_preventive_and_curative_HVDC.xml @@ -0,0 +1,161 @@ + + + CIM_CRAC_DOCUMENT + 1 + B15 + A48 + FAKE + A36 + FAKE + A04 + 2021-03-31T15:02:00Z + + A42 + + + 2021-04-01T22:00Z + 2021-04-02T22:00Z + + 10YCB-FR-ES-PT-S + + TimeSeries + B54 + A03 + 1------0 + 1------0 + + + 2021-04-01T22:00Z + 2021-04-02T22:00Z + + PT60M + + 2 + + Contingencies_1 + B55 + Contingencies_1 + A52 + + Co-1 + Contingency name + + FFR1AA11 FFR3AA11 1 + FFR1AA11 FFR3AA11 1 + 10YFR-RTE------C + 10YFR-RTE------C + + + + + RA-Series-1 + B56 + HVDC valid range actions + A52 + + HVDC-direction11 + HVDC-direction11-ra + B59 + A27 + A39 + + BBE2AA11 FFR3AA11 1 + PMode on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + A43 + + + BBE2AA11 FFR3AA11 1 + RangeAction on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + FFR3AA1 + BBE2AA1 + A26 + 5000.0 + 0 + 500.0 + MAW + + + BBE2AA12 FFR3AA12 1 + PMode on HVDC BE2 FR3 2 + B22 + 1------C + 1------C2 + A43 + + + BBE2AA12 FFR3AA12 1 + RangeAction on HVDC BE2 FR3 2 + B22 + 1------C + 1------C + FFR3AA1 + BBE2AA1 + A26 + 3500.0 + 0 + 500.0 + MAW + + + + HVDC-direction12 + HVDC-direction12-ra + B59 + A27 + A39 + + BBE2AA11 FFR3AA11 1 + PMode on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + A43 + + + BBE2AA11 FFR3AA11 1 + RangeAction on HVDC BE2 FR3 1 + B22 + 1------C + 1------C + BBE2AA1 + FFR3AA1 + A26 + 4000.0 + 0 + 500.0 + MAW + + + BBE2AA12 FFR3AA12 1 + PMode on HVDC BE2 FR3 2 + B22 + 1------C + 1------C + A43 + + + BBE2AA12 FFR3AA12 1 + RangeAction on HVDC BE2 FR3 2 + B22 + 1------C + 1------C + BBE2AA1 + FFR3AA1 + A26 + 3000.0 + 0 + 500.0 + MAW + + + + + + + \ No newline at end of file