From 4d9293cf847766bfb0ce1c2b07ea0f33cf92b9ab Mon Sep 17 00:00:00 2001 From: EtienneLt <32468651+EtienneLt@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:19:14 +0200 Subject: [PATCH] check null values for droop and P0 (#512) --- .../server/NetworkModificationException.java | 4 +- .../server/modifications/VscCreation.java | 45 +++--- .../server/modifications/VscModification.java | 131 ++++++++++-------- .../server/modifications/VscCreationTest.java | 34 ++++- .../modifications/VscModificationTest.java | 82 ++++++++--- 5 files changed, 197 insertions(+), 99 deletions(-) diff --git a/src/main/java/org/gridsuite/modification/server/NetworkModificationException.java b/src/main/java/org/gridsuite/modification/server/NetworkModificationException.java index 139111089..530d3b4c0 100644 --- a/src/main/java/org/gridsuite/modification/server/NetworkModificationException.java +++ b/src/main/java/org/gridsuite/modification/server/NetworkModificationException.java @@ -114,8 +114,8 @@ public enum Type { MODIFY_CONVERTER_STATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), BY_FORMULA_MODIFICATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), HVDC_LINE_NOT_FOUND(HttpStatus.NOT_FOUND), - COMPOSITE_MODIFICATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR); - + COMPOSITE_MODIFICATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), + WRONG_HVDC_ANGLE_DROOP_ACTIVE_POWER_CONTROL(HttpStatus.BAD_REQUEST); public final HttpStatus status; private final String message; diff --git a/src/main/java/org/gridsuite/modification/server/modifications/VscCreation.java b/src/main/java/org/gridsuite/modification/server/modifications/VscCreation.java index 7f84d7644..1fc716c85 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/VscCreation.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/VscCreation.java @@ -11,13 +11,7 @@ import com.powsybl.commons.report.TypedValue; import com.powsybl.iidm.modification.topology.CreateFeederBay; import com.powsybl.iidm.modification.topology.CreateFeederBayBuilder; -import com.powsybl.iidm.network.Bus; -import com.powsybl.iidm.network.HvdcLine; -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.TopologyKind; -import com.powsybl.iidm.network.VoltageLevel; -import com.powsybl.iidm.network.VscConverterStation; -import com.powsybl.iidm.network.VscConverterStationAdder; +import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.extensions.HvdcAngleDroopActivePowerControlAdder; import com.powsybl.iidm.network.extensions.HvdcOperatorActivePowerRangeAdder; import org.gridsuite.modification.server.NetworkModificationException; @@ -28,8 +22,8 @@ import java.util.List; import java.util.Map; -import static org.gridsuite.modification.server.NetworkModificationException.Type.CREATE_VSC_ERROR; -import static org.gridsuite.modification.server.NetworkModificationException.Type.HVDC_LINE_ALREADY_EXISTS; +import static org.gridsuite.modification.server.NetworkModificationException.Type.*; +import static org.gridsuite.modification.server.modifications.VscModification.DROOP_ACTIVE_POWER_CONTROL_P0_DROOP_REQUIRED_ERROR_MSG; /** * @author Seddik Yengui @@ -54,6 +48,20 @@ public void check(Network network) throws NetworkModificationException { checkConverterStation(network, modificationInfos.getConverterStation1()); checkConverterStation(network, modificationInfos.getConverterStation2()); + checkDroop(); + } + + private void checkDroop() { + // extension is not enabled => ignore check inside fields + if (!Boolean.TRUE.equals(modificationInfos.getAngleDroopActivePowerControl())) { + return; + } + + // enable the extension => should verify whether all fields have been filled + if (modificationInfos.getDroop() == null || modificationInfos.getP0() == null) { + throw new NetworkModificationException(WRONG_HVDC_ANGLE_DROOP_ACTIVE_POWER_CONTROL, + String.format(DROOP_ACTIVE_POWER_CONTROL_P0_DROOP_REQUIRED_ERROR_MSG)); + } } private void checkConverterStation(Network network, @@ -100,20 +108,15 @@ public void apply(Network network, ReportNode subReportNode) { .add(); } - if (modificationInfos.getDroop() != null || - modificationInfos.getP0() != null) { + if (shouldCreateDroopActivePowerControlExtension()) { var activePowerControlExtension = hvdcLine.newExtension(HvdcAngleDroopActivePowerControlAdder.class) .withEnabled(modificationInfos.getAngleDroopActivePowerControl()); - if (modificationInfos.getP0() != null) { - activePowerControlExtension.withP0(modificationInfos.getP0()); - } - - if (modificationInfos.getDroop() != null) { - activePowerControlExtension.withDroop(modificationInfos.getDroop()); - } + activePowerControlExtension.withP0(modificationInfos.getP0()); + activePowerControlExtension.withDroop(modificationInfos.getDroop()); activePowerControlExtension.add(); } + reportHvdcLineInfos(subReportNode); subReportNode.newReportNode() @@ -130,6 +133,12 @@ public void apply(Network network, ReportNode subReportNode) { PropertiesUtils.applyProperties(hvdcLine, subReportNode, modificationInfos.getProperties(), "VscProperties"); } + private boolean shouldCreateDroopActivePowerControlExtension() { + return Boolean.TRUE.equals(modificationInfos.getAngleDroopActivePowerControl()) && + modificationInfos.getDroop() != null && + modificationInfos.getP0() != null; + } + private void reportHvdcLineInfos(ReportNode subReportNode) { List characteristicsReports = new ArrayList<>(); characteristicsReports.add(ModificationUtils.getInstance().buildCreationReport(modificationInfos.getNominalV(), "DC nominal voltage")); diff --git a/src/main/java/org/gridsuite/modification/server/modifications/VscModification.java b/src/main/java/org/gridsuite/modification/server/modifications/VscModification.java index 0eb7956b9..34d6f102a 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/VscModification.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/VscModification.java @@ -13,16 +13,15 @@ import com.powsybl.iidm.network.extensions.HvdcAngleDroopActivePowerControlAdder; import com.powsybl.iidm.network.extensions.HvdcOperatorActivePowerRange; import com.powsybl.iidm.network.extensions.HvdcOperatorActivePowerRangeAdder; -import io.micrometer.common.lang.NonNull; import org.gridsuite.modification.server.NetworkModificationException; import org.gridsuite.modification.server.dto.ConverterStationModificationInfos; import org.gridsuite.modification.server.dto.ReactiveCapabilityCurveModificationInfos; import org.gridsuite.modification.server.dto.VscModificationInfos; +import javax.annotation.Nonnull; import java.util.*; -import static org.gridsuite.modification.server.NetworkModificationException.Type.MODIFY_BATTERY_ERROR; -import static org.gridsuite.modification.server.NetworkModificationException.Type.MODIFY_VSC_ERROR; +import static org.gridsuite.modification.server.NetworkModificationException.Type.*; import static org.gridsuite.modification.server.modifications.VscCreation.VSC_CHARACTERISTICS; import static org.gridsuite.modification.server.modifications.VscCreation.VSC_SETPOINTS; @@ -31,14 +30,20 @@ */ public class VscModification extends AbstractModification { + public static final String NO_VALUE = "No value"; + public static final String ANGLE_DROOP_ACTIVE_POWER_CONTROL_FIELD = "AngleDroopActivePowerControl"; + public static final String DROOP_FIELD = "Droop"; + public static final String P0_FIELD = "P0"; + public static final String DROOP_ACTIVE_POWER_CONTROL_P0_DROOP_REQUIRED_ERROR_MSG = "Both Droop and P0 are required when angle droop active power control is activated"; + public static final String DROOP_ACTIVE_POWER_CONTROL_P0_REQUIRED_ERROR_MSG = "P0 is required when Droop is provided"; + private final VscModificationInfos modificationInfos; - private static final String NO_VALUE = "No value"; public VscModification(VscModificationInfos vscModificationInfos) { this.modificationInfos = vscModificationInfos; } - protected void checkConverterStation(@NonNull ConverterStationModificationInfos converterStationModificationInfos, @NonNull VscConverterStation vscConverterStation) { + protected void checkConverterStation(@Nonnull ConverterStationModificationInfos converterStationModificationInfos, @Nonnull VscConverterStation vscConverterStation) { String errorMessage = "Converter station '" + converterStationModificationInfos.getEquipmentId() + "' : "; ModificationUtils.getInstance().checkReactiveLimit(vscConverterStation, converterStationModificationInfos.getMinQ(), converterStationModificationInfos.getMaxQ(), converterStationModificationInfos.getReactiveCapabilityCurvePoints(), MODIFY_VSC_ERROR, errorMessage); @@ -57,15 +62,32 @@ public void check(Network network) throws NetworkModificationException { VscConverterStation converterStation2 = ModificationUtils.getInstance().getVscConverterStation(network, hvdcLine.getConverterStation2().getId()); checkConverterStation(modificationInfos.getConverterStation1(), converterStation1); checkConverterStation(modificationInfos.getConverterStation2(), converterStation2); + checkDroopModification(hvdcLine); + } - checkDroopModification(); + private void checkDroopModification(HvdcLine hvdcLine) { + // the extension already exists + HvdcAngleDroopActivePowerControl hvdcAngleDroopActivePowerControl = hvdcLine.getExtension(HvdcAngleDroopActivePowerControl.class); + if (hvdcAngleDroopActivePowerControl != null) { + // if droop is set p0 should be also + if (modificationInfos.getDroop() != null && modificationInfos.getP0() == null) { + throw new NetworkModificationException(WRONG_HVDC_ANGLE_DROOP_ACTIVE_POWER_CONTROL, + String.format(DROOP_ACTIVE_POWER_CONTROL_P0_REQUIRED_ERROR_MSG)); + } + return; + } - } + // the extension doesn't exist yet and the modification wants to enable the extension => + // should verify whether all fields have been filled + boolean isEnabledAngleDroopActivePowerControl = modificationInfos.getAngleDroopActivePowerControl() != null + && Boolean.TRUE.equals(modificationInfos.getAngleDroopActivePowerControl().getValue()); + if (!isEnabledAngleDroopActivePowerControl) { + return; + } - private void checkDroopModification() { - // if droop is set p0 should be also - if (modificationInfos.getP0() == null && modificationInfos.getDroop() != null) { - throw new NetworkModificationException(MODIFY_VSC_ERROR, "P0 is required to modify the equipment"); + if (modificationInfos.getDroop() == null || modificationInfos.getP0() == null) { + throw new NetworkModificationException(WRONG_HVDC_ANGLE_DROOP_ACTIVE_POWER_CONTROL, + String.format(DROOP_ACTIVE_POWER_CONTROL_P0_DROOP_REQUIRED_ERROR_MSG)); } } @@ -75,7 +97,7 @@ public void apply(Network network, ReportNode subReportNode) { modifyVsc(network, hvdcLine, modificationInfos, subReportNode); } - private void modifyVsc(@NonNull Network network, @NonNull HvdcLine hvdcLine, VscModificationInfos modificationInfos, ReportNode subReportNode) { + private void modifyVsc(@Nonnull Network network, @Nonnull HvdcLine hvdcLine, VscModificationInfos modificationInfos, ReportNode subReportNode) { subReportNode.newReportNode() .withMessageTemplate("VscModification", "Vsc with id=${id} modified :") .withUntypedValue("id", modificationInfos.getEquipmentId()) @@ -196,32 +218,33 @@ private static void createOperatorActiveRangeExt(HvdcLine hvdcLine, VscModificat } private void modifyExistingHvdcAngleDroopActivePowerControl(HvdcAngleDroopActivePowerControl hvdcAngleDroopActivePowerControl, List reports) { - var isEnabled = hvdcAngleDroopActivePowerControl.isEnabled(); - var oldDroop = hvdcAngleDroopActivePowerControl.getDroop(); - var oldP0 = hvdcAngleDroopActivePowerControl.getP0(); - Optional.ofNullable(modificationInfos.getAngleDroopActivePowerControl()).ifPresent(info -> { - if (info.getValue() == null) { - return; - } - hvdcAngleDroopActivePowerControl.setEnabled(info.getValue()); - reports.add(ModificationUtils.getInstance().buildModificationReport(isEnabled, info.getValue(), "AngleDroopActivePowerControl")); - }); - - Optional.ofNullable(modificationInfos.getDroop()).ifPresent(info -> { - hvdcAngleDroopActivePowerControl.setDroop(info.getValue()); - reports.add(ModificationUtils.getInstance().buildModificationReport(oldDroop, info.getValue(), "Droop")); - }); - - Optional.ofNullable(modificationInfos.getP0()).ifPresent(info -> { - hvdcAngleDroopActivePowerControl.setP0(info.getValue()); - reports.add(ModificationUtils.getInstance().buildModificationReport(oldP0, info.getValue(), "P0")); - }); + Optional.ofNullable(modificationInfos.getAngleDroopActivePowerControl()).ifPresent(modification -> + reports.add(ModificationUtils.getInstance().applyAndBuildModificationReport( + hvdcAngleDroopActivePowerControl::setEnabled, + hvdcAngleDroopActivePowerControl::isEnabled, + modification, + ANGLE_DROOP_ACTIVE_POWER_CONTROL_FIELD))); + + Optional.ofNullable(modificationInfos.getDroop()).ifPresent(modification -> + reports.add(ModificationUtils.getInstance().applyAndBuildModificationReport( + hvdcAngleDroopActivePowerControl::setDroop, + hvdcAngleDroopActivePowerControl::getDroop, + modification, + DROOP_FIELD))); + + Optional.ofNullable(modificationInfos.getP0()).ifPresent(modification -> + reports.add(ModificationUtils.getInstance().applyAndBuildModificationReport( + hvdcAngleDroopActivePowerControl::setP0, + hvdcAngleDroopActivePowerControl::getP0, + modification, + P0_FIELD))); } - protected boolean checkIfChangeRequestedOnDropActiveControl() { - return modificationInfos.getAngleDroopActivePowerControl() == null - && modificationInfos.getDroop() == null - && modificationInfos.getP0() == null; + private boolean shouldCreateDroopActivePowerControlExtension() { + return modificationInfos.getAngleDroopActivePowerControl() != null && + modificationInfos.getAngleDroopActivePowerControl().getValue() && + modificationInfos.getDroop() != null && + modificationInfos.getP0() != null; } private List hvdcAngleDroopActivePowerControlAdder(HvdcLine hvdcLine) { @@ -229,30 +252,23 @@ private List hvdcAngleDroopActivePowerControlAdder(HvdcLine hvdcLine var hvdcAngleDroopActivePowerControl = hvdcLine.getExtension(HvdcAngleDroopActivePowerControl.class); if (hvdcAngleDroopActivePowerControl != null) { modifyExistingHvdcAngleDroopActivePowerControl(hvdcAngleDroopActivePowerControl, reports); - } else { - var activePowerControlExtension = hvdcLine.newExtension(HvdcAngleDroopActivePowerControlAdder.class); + } else if (shouldCreateDroopActivePowerControlExtension()) { + HvdcAngleDroopActivePowerControlAdder hvdcAngleDroopActivePowerControlAdder = + hvdcLine.newExtension(HvdcAngleDroopActivePowerControlAdder.class); - if (checkIfChangeRequestedOnDropActiveControl()) { - return Collections.emptyList(); - } - boolean isEnabled = modificationInfos.getAngleDroopActivePowerControl() != null && modificationInfos.getAngleDroopActivePowerControl().getValue(); - if (modificationInfos.getAngleDroopActivePowerControl() != null) { - activePowerControlExtension.withEnabled(isEnabled); - reports.add(ModificationUtils.getInstance().buildModificationReport(null, isEnabled, "AngleDroopActivePowerControl")); - } + Boolean isEnabled = modificationInfos.getAngleDroopActivePowerControl().getValue(); + hvdcAngleDroopActivePowerControlAdder.withEnabled(isEnabled); + reports.add(ModificationUtils.getInstance().buildModificationReport(null, isEnabled, ANGLE_DROOP_ACTIVE_POWER_CONTROL_FIELD)); - var droop = modificationInfos.getDroop() != null ? modificationInfos.getDroop().getValue() : Float.NaN; - activePowerControlExtension.withDroop(droop); - if (modificationInfos.getDroop() != null) { - reports.add(ModificationUtils.getInstance().buildModificationReport(Float.NaN, droop, "Droop")); - } - var p0 = modificationInfos.getP0() != null ? modificationInfos.getP0().getValue() : Float.NaN; - activePowerControlExtension.withP0(p0); - if (modificationInfos.getP0() != null) { - reports.add(ModificationUtils.getInstance().buildModificationReport(Float.NaN, p0, "P0")); - } - activePowerControlExtension.add(); + Float droop = modificationInfos.getDroop().getValue(); + hvdcAngleDroopActivePowerControlAdder.withDroop(droop); + reports.add(ModificationUtils.getInstance().buildModificationReport(Float.NaN, droop, DROOP_FIELD)); + Float p0 = modificationInfos.getP0().getValue(); + hvdcAngleDroopActivePowerControlAdder.withP0(p0); + reports.add(ModificationUtils.getInstance().buildModificationReport(Float.NaN, p0, P0_FIELD)); + + hvdcAngleDroopActivePowerControlAdder.add(); } return reports; } @@ -340,5 +356,4 @@ private void modifyVscReactiveLimitsAttributes(ConverterStationModificationInfos } } } - } diff --git a/src/test/java/org/gridsuite/modification/server/modifications/VscCreationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/VscCreationTest.java index 3dc622642..32830a39b 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/VscCreationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/VscCreationTest.java @@ -24,7 +24,9 @@ import java.util.Map; import java.util.UUID; +import static org.assertj.core.api.Assertions.assertThat; import static org.gridsuite.modification.server.NetworkModificationException.Type.*; +import static org.gridsuite.modification.server.modifications.VscModification.DROOP_ACTIVE_POWER_CONTROL_P0_DROOP_REQUIRED_ERROR_MSG; import static org.gridsuite.modification.server.utils.TestUtils.assertLogMessage; import static org.junit.Assert.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -60,7 +62,7 @@ protected ModificationInfos buildModification() { .operatorActivePowerLimitFromSide1ToSide2(6.0F) .operatorActivePowerLimitFromSide2ToSide1(8F) .droop(1F) - .angleDroopActivePowerControl(false) + .angleDroopActivePowerControl(true) .converterStation1(buildConverterStationWithReactiveCapabilityCurve()) .converterStation2(buildConverterStationWithMinMaxReactiveLimits()) .properties(List.of(FreePropertyInfos.builder().name(PROPERTY_NAME).value(PROPERTY_VALUE).build())) @@ -298,4 +300,34 @@ public void testCreateWithErrors() throws Exception { assertLogMessage(new NetworkModificationException(HVDC_LINE_ALREADY_EXISTS, "hvdcLine").getMessage(), vscCreationInfos.getErrorType().name(), reportService); } + + @Test + public void testCreateWithoutEnablingDroopPowerControl() throws Exception { + // create without enabling droop power control + VscCreationInfos vscCreationInfos = (VscCreationInfos) buildModification(); + vscCreationInfos.setAngleDroopActivePowerControl(false); + String vscCreationInfosJson = mapper.writeValueAsString(vscCreationInfos); + mockMvc.perform(post(getNetworkModificationUri()).content(vscCreationInfosJson).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + assertThat(getNetwork().getHvdcLine("vsc1")).isNotNull(); + HvdcLine hvdcLine = getNetwork().getHvdcLine("vsc1"); + assertThat(hvdcLine).isNotNull(); + HvdcAngleDroopActivePowerControl activePowerControl = hvdcLine.getExtension(HvdcAngleDroopActivePowerControl.class); + assertThat(activePowerControl).isNull(); + } + + @Test + public void testCreateWithEnablingDroopPowerControl() throws Exception { + // create with enabling droop power control but not provide Droop and P0 + VscCreationInfos vscCreationInfos = (VscCreationInfos) buildModification(); + vscCreationInfos.setAngleDroopActivePowerControl(true); + vscCreationInfos.setDroop(null); + vscCreationInfos.setP0(null); + String vscCreationInfosJson = mapper.writeValueAsString(vscCreationInfos); + mockMvc.perform(post(getNetworkModificationUri()).content(vscCreationInfosJson).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + assertLogMessage(new NetworkModificationException(WRONG_HVDC_ANGLE_DROOP_ACTIVE_POWER_CONTROL, + String.format(DROOP_ACTIVE_POWER_CONTROL_P0_DROOP_REQUIRED_ERROR_MSG)).getMessage(), + vscCreationInfos.getErrorType().name(), reportService); + } } diff --git a/src/test/java/org/gridsuite/modification/server/modifications/VscModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/VscModificationTest.java index caaa54e9a..e5b3b6996 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/VscModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/VscModificationTest.java @@ -28,6 +28,9 @@ import java.util.*; import java.util.stream.IntStream; +import static org.assertj.core.api.Assertions.assertThat; +import static org.gridsuite.modification.server.NetworkModificationException.Type.WRONG_HVDC_ANGLE_DROOP_ACTIVE_POWER_CONTROL; +import static org.gridsuite.modification.server.modifications.VscModification.DROOP_ACTIVE_POWER_CONTROL_P0_DROOP_REQUIRED_ERROR_MSG; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; @@ -223,28 +226,76 @@ protected void assertAfterNetworkModificationDeletion() { @Test public void testActivateHvdcAngleDroopActivePowerControl() throws Exception { var networkuuid = UUID.randomUUID(); - Network networkWitoutExt = NetworkCreation.createWithVSC(networkuuid, false); + Network networkWithoutExt = NetworkCreation.createWithVSC(networkuuid, false); VscModificationInfos modificationInfos = (VscModificationInfos) buildModification(); modificationInfos.setAngleDroopActivePowerControl(new AttributeModification<>(true, OperationType.SET)); VscModification vscModification = new VscModification(modificationInfos); ReportNode subReporter = ReportNode.NO_OP; ComputationManager computationManager = new LocalComputationManager(); - vscModification.apply(networkWitoutExt, true, computationManager, subReporter); + vscModification.apply(networkWithoutExt, true, computationManager, subReporter); - HvdcLine hvdcLine = networkWitoutExt.getHvdcLine("hvdcLine"); + HvdcLine hvdcLine = networkWithoutExt.getHvdcLine("hvdcLine"); assertNotNull(hvdcLine); HvdcAngleDroopActivePowerControl activePowerControl = hvdcLine.getExtension(HvdcAngleDroopActivePowerControl.class); + assertNotNull(activePowerControl); Assert.assertEquals(5, activePowerControl.getP0(), 0); Assert.assertEquals(1, activePowerControl.getDroop(), 0); Assert.assertTrue(activePowerControl.isEnabled()); + } + @Test + public void testActivateHvdcAngleDroopActivePowerControlWithNullValues() { + var networkuuid = UUID.randomUUID(); + Network networkWithoutExt = NetworkCreation.createWithVSC(networkuuid, false); + VscModificationInfos wrongModificationInfos = (VscModificationInfos) buildModification(); + wrongModificationInfos.setDroop(null); + wrongModificationInfos.setP0(null); + wrongModificationInfos.setAngleDroopActivePowerControl(new AttributeModification<>(true, OperationType.SET)); + VscModification wrongVscModification = new VscModification(wrongModificationInfos); + String message = Assert.assertThrows(NetworkModificationException.class, + () -> wrongVscModification.check(networkWithoutExt)) + .getMessage(); + assertThat(message).isEqualTo(WRONG_HVDC_ANGLE_DROOP_ACTIVE_POWER_CONTROL.name() + " : " + + String.format(DROOP_ACTIVE_POWER_CONTROL_P0_DROOP_REQUIRED_ERROR_MSG)); } @Test - public void testUnchangedHVDCangleDroopActivePowerControl() throws Exception { + public void testActivateHvdcAngleDroopActivePowerControlWithDroopNull() { var networkuuid = UUID.randomUUID(); - Network networkWitoutExt = NetworkCreation.createWithVSC(networkuuid, true); + Network networkWithoutExt = NetworkCreation.createWithVSC(networkuuid, false); + VscModificationInfos wrongModificationInfos = (VscModificationInfos) buildModification(); + wrongModificationInfos.setDroop(null); + wrongModificationInfos.setP0(new AttributeModification<>(100f, OperationType.SET)); + wrongModificationInfos.setAngleDroopActivePowerControl(new AttributeModification<>(true, OperationType.SET)); + VscModification wrongVscModification = new VscModification(wrongModificationInfos); + String message = Assert.assertThrows(NetworkModificationException.class, + () -> wrongVscModification.check(networkWithoutExt)) + .getMessage(); + assertThat(message).isEqualTo(WRONG_HVDC_ANGLE_DROOP_ACTIVE_POWER_CONTROL.name() + " : " + + String.format(DROOP_ACTIVE_POWER_CONTROL_P0_DROOP_REQUIRED_ERROR_MSG)); + } + + @Test + public void testActivateHvdcAngleDroopActivePowerControlWithP0Null() { + var networkuuid = UUID.randomUUID(); + Network networkWithoutExt = NetworkCreation.createWithVSC(networkuuid, false); + VscModificationInfos wrongModificationInfos = (VscModificationInfos) buildModification(); + wrongModificationInfos.setDroop(new AttributeModification<>(20f, OperationType.SET)); + wrongModificationInfos.setP0(null); + wrongModificationInfos.setAngleDroopActivePowerControl(new AttributeModification<>(true, OperationType.SET)); + VscModification wrongVscModification = new VscModification(wrongModificationInfos); + String message = Assert.assertThrows(NetworkModificationException.class, + () -> wrongVscModification.check(networkWithoutExt)) + .getMessage(); + assertThat(message).isEqualTo(WRONG_HVDC_ANGLE_DROOP_ACTIVE_POWER_CONTROL.name() + " : " + + String.format(DROOP_ACTIVE_POWER_CONTROL_P0_DROOP_REQUIRED_ERROR_MSG)); + } + + @Test + public void testUnchangedHvdcAngleDroopActivePowerControl() throws Exception { + var networkuuid = UUID.randomUUID(); + Network networkWithExt = NetworkCreation.createWithVSC(networkuuid, true); VscModificationInfos modificationInfos = (VscModificationInfos) buildModification(); modificationInfos.setConverterStation1(null); modificationInfos.setConverterStation2(null); @@ -254,8 +305,8 @@ public void testUnchangedHVDCangleDroopActivePowerControl() throws Exception { VscModification vscModification = new VscModification(modificationInfos); ReportNode subReporter = ReportNode.NO_OP; ComputationManager computationManager = new LocalComputationManager(); - vscModification.apply(networkWitoutExt, true, computationManager, subReporter); - HvdcLine hvdcLine = networkWitoutExt.getHvdcLine("hvdcLine"); + vscModification.apply(networkWithExt, true, computationManager, subReporter); + HvdcLine hvdcLine = networkWithExt.getHvdcLine("hvdcLine"); HvdcAngleDroopActivePowerControl activePowerControl = hvdcLine.getExtension(HvdcAngleDroopActivePowerControl.class); Assert.assertEquals(0, activePowerControl.getP0(), 0); Assert.assertEquals(10, activePowerControl.getDroop(), 0); @@ -265,23 +316,22 @@ public void testUnchangedHVDCangleDroopActivePowerControl() throws Exception { @Test public void testHvdcAngleDroopActivePowerControlWithoutP0() { var networkuuid = UUID.randomUUID(); - Network networkWitoutExt = NetworkCreation.createWithVSC(networkuuid, true); + Network networkWithExt = NetworkCreation.createWithVSC(networkuuid, true); VscModificationInfos modificationInfos = (VscModificationInfos) buildModification(); modificationInfos.setAngleDroopActivePowerControl(new AttributeModification<>(true, OperationType.SET)); { //Test : p0 should be required if drop is changed modificationInfos.setDroop(new AttributeModification<>(10F, OperationType.SET)); modificationInfos.setP0(null); VscModification vscModification = new VscModification(modificationInfos); - Assert.assertThrows(NetworkModificationException.class, () -> vscModification.check(networkWitoutExt)); + Assert.assertThrows(NetworkModificationException.class, () -> vscModification.check(networkWithExt)); } { //Test : p0 should not be required if drop unchanged modificationInfos.setDroop(null); - modificationInfos.setP0(new AttributeModification<>(10F, OperationType.SET)); + modificationInfos.setP0(null); VscModification vscModification = new VscModification(modificationInfos); - assertDoesNotThrow(() -> vscModification.check(networkWitoutExt)); + assertDoesNotThrow(() -> vscModification.check(networkWithExt)); } - } @Override @@ -292,14 +342,6 @@ protected void testUpdateModificationMessage(ModificationInfos modificationInfos assertEquals("vsc1Edited", updatedValues.get("equipmentId")); } - @Test - public void testIscheckIfChangeRequestedOnDropActiveControl() { - VscModificationInfos modificationInfos = (VscModificationInfos) buildModification(); - modificationInfos.setAngleDroopActivePowerControl(new AttributeModification<>(true, OperationType.SET)); - VscModification vscModification = new VscModification(modificationInfos); - Assert.assertFalse(vscModification.checkIfChangeRequestedOnDropActiveControl()); - } - @Test public void testDtoContainRequiredData() { VscModificationInfos modificationInfos = VscModificationInfos.builder()