From 41ec5c2c0ded7293448c7d5ae7dc0f648d2dfe72 Mon Sep 17 00:00:00 2001 From: Ghazoua Rehili Date: Thu, 19 Sep 2024 17:11:14 +0200 Subject: [PATCH] implement connectablePosition modification for branch form (#530) Signed-off-by: Ghazwa Rehili --- .../server/dto/BranchModificationInfos.java | 35 +- .../BranchModificationEntity.java | 95 ++++- .../modification/LineModificationEntity.java | 14 +- ...WindingsTransformerModificationEntity.java | 14 +- .../AbstractBranchModification.java | 19 +- .../modifications/ModificationUtils.java | 327 +++++++++++------- .../changesets/changelog_20240904T211456Z.xml | 127 +++++++ .../db/changelog/db.changelog-master.yaml | 3 + .../modifications/LineModificationTest.java | 15 +- ...woWindingsTransformerModificationTest.java | 15 +- 10 files changed, 526 insertions(+), 138 deletions(-) create mode 100644 src/main/resources/db/changelog/changesets/changelog_20240904T211456Z.xml diff --git a/src/main/java/org/gridsuite/modification/server/dto/BranchModificationInfos.java b/src/main/java/org/gridsuite/modification/server/dto/BranchModificationInfos.java index 97605d817..50a4eae5c 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/BranchModificationInfos.java +++ b/src/main/java/org/gridsuite/modification/server/dto/BranchModificationInfos.java @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.gridsuite.modification.server.dto; +import com.powsybl.iidm.network.extensions.ConnectablePosition; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.NoArgsConstructor; @@ -35,9 +36,39 @@ public class BranchModificationInfos extends BasicEquipmentModificationInfos { @Schema(description = "Current limits Side 2") private CurrentLimitsModificationInfos currentLimits2; + @Schema(description = "Voltage level id modification 1") + private AttributeModification voltageLevelId1; + + @Schema(description = "Voltage level id modification 2") + private AttributeModification voltageLevelId2; + + @Schema(description = "Bus id modification 1") + private AttributeModification busOrBusbarSectionId1; + + @Schema(description = "Bus id modification 2") + private AttributeModification busOrBusbarSectionId2; + + @Schema(description = "Connection Name 1") + private AttributeModification connectionName1; + + @Schema(description = "Connection Name 2") + private AttributeModification connectionName2; + + @Schema(description = "Connection Direction 1") + private AttributeModification connectionDirection1; + + @Schema(description = "Connection Direction 2") + private AttributeModification connectionDirection2; + + @Schema(description = "Connection Position 1") + private AttributeModification connectionPosition1; + + @Schema(description = "Connection Position 2") + private AttributeModification connectionPosition2; + @Schema(description = "Connected 1") - private AttributeModification connected1; + private AttributeModification terminal1Connected; @Schema(description = "Connected 2") - private AttributeModification connected2; + private AttributeModification terminal2Connected; } diff --git a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/BranchModificationEntity.java b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/BranchModificationEntity.java index 672d4d433..128341b55 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/BranchModificationEntity.java +++ b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/BranchModificationEntity.java @@ -6,14 +6,13 @@ */ package org.gridsuite.modification.server.entities.equipment.modification; +import com.powsybl.iidm.network.extensions.ConnectablePosition; +import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; import org.gridsuite.modification.server.dto.BranchModificationInfos; import org.gridsuite.modification.server.dto.ModificationInfos; -import org.gridsuite.modification.server.entities.equipment.modification.attribute.BooleanModificationEmbedded; -import org.gridsuite.modification.server.entities.equipment.modification.attribute.DoubleModificationEmbedded; - -import jakarta.persistence.*; +import org.gridsuite.modification.server.entities.equipment.modification.attribute.*; /** * @author Ayoub LABIDI @@ -53,19 +52,89 @@ public class BranchModificationEntity extends BasicEquipmentModificationEntity { ), nullable = true) private CurrentLimitsModificationEntity currentLimits2; + @Embedded + @AttributeOverrides(value = { + @AttributeOverride(name = "value", column = @Column(name = "voltageLevelId1")), + @AttributeOverride(name = "opType", column = @Column(name = "voltageLevelId1Op")) + }) + private StringModificationEmbedded voltageLevelId1; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride(name = "value", column = @Column(name = "voltageLevelId2")), + @AttributeOverride(name = "opType", column = @Column(name = "voltageLevelId2Op")) + }) + private StringModificationEmbedded voltageLevelId2; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride(name = "value", column = @Column(name = "busOrBusbarSectionId1")), + @AttributeOverride(name = "opType", column = @Column(name = "busOrBusbarSectionId1Op")) + }) + private StringModificationEmbedded busOrBusbarSectionId1; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride(name = "value", column = @Column(name = "busOrBusbarSectionId2")), + @AttributeOverride(name = "opType", column = @Column(name = "busOrBusbarSectionId2Op")) + }) + private StringModificationEmbedded busOrBusbarSectionId2; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride(name = "value", column = @Column(name = "connectionName1")), + @AttributeOverride(name = "opType", column = @Column(name = "connectionName1Op")) + }) + private StringModificationEmbedded connectionName1; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride(name = "value", column = @Column(name = "connectionName2")), + @AttributeOverride(name = "opType", column = @Column(name = "connectionName2Op")) + }) + private StringModificationEmbedded connectionName2; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride(name = "value", column = @Column(name = "connectionPosition1")), + @AttributeOverride(name = "opType", column = @Column(name = "connectionPosition1Op")) + }) + private IntegerModificationEmbedded connectionPosition1; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride(name = "value", column = @Column(name = "connectionPosition2")), + @AttributeOverride(name = "opType", column = @Column(name = "connectionPosition2Op")) + }) + private IntegerModificationEmbedded connectionPosition2; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride(name = "value", column = @Column(name = "connectionDirection1")), + @AttributeOverride(name = "opType", column = @Column(name = "connectionDirection1Op")) + }) + private EnumModificationEmbedded connectionDirection1; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride(name = "value", column = @Column(name = "connectionDirection2")), + @AttributeOverride(name = "opType", column = @Column(name = "connectionDirection2Op")) + }) + private EnumModificationEmbedded connectionDirection2; + @Embedded @AttributeOverrides(value = { @AttributeOverride(name = "value", column = @Column(name = "connected1")), @AttributeOverride(name = "opType", column = @Column(name = "connected1Op")) }) - private BooleanModificationEmbedded connected1; + private BooleanModificationEmbedded terminal1Connected; @Embedded @AttributeOverrides(value = { @AttributeOverride(name = "value", column = @Column(name = "connected2")), @AttributeOverride(name = "opType", column = @Column(name = "connected2Op")) }) - private BooleanModificationEmbedded connected2; + private BooleanModificationEmbedded terminal2Connected; protected BranchModificationEntity(BranchModificationInfos branchModificationInfos) { super(branchModificationInfos); @@ -92,7 +161,17 @@ private void assignAttributes(BranchModificationInfos branchModificationInfos) { } else { currentLimits2 = branchModificationInfos.getCurrentLimits2().toEntity(); } - this.connected1 = branchModificationInfos.getConnected1() != null ? new BooleanModificationEmbedded(branchModificationInfos.getConnected1()) : null; - this.connected2 = branchModificationInfos.getConnected2() != null ? new BooleanModificationEmbedded(branchModificationInfos.getConnected2()) : null; + this.voltageLevelId1 = branchModificationInfos.getVoltageLevelId1() != null ? new StringModificationEmbedded(branchModificationInfos.getVoltageLevelId1()) : null; + this.voltageLevelId2 = branchModificationInfos.getVoltageLevelId2() != null ? new StringModificationEmbedded(branchModificationInfos.getVoltageLevelId2()) : null; + this.busOrBusbarSectionId1 = branchModificationInfos.getBusOrBusbarSectionId1() != null ? new StringModificationEmbedded(branchModificationInfos.getBusOrBusbarSectionId1()) : null; + this.busOrBusbarSectionId2 = branchModificationInfos.getBusOrBusbarSectionId2() != null ? new StringModificationEmbedded(branchModificationInfos.getBusOrBusbarSectionId2()) : null; + this.connectionName1 = branchModificationInfos.getConnectionName1() != null ? new StringModificationEmbedded(branchModificationInfos.getConnectionName1()) : null; + this.connectionName2 = branchModificationInfos.getConnectionName2() != null ? new StringModificationEmbedded(branchModificationInfos.getConnectionName2()) : null; + this.connectionDirection1 = branchModificationInfos.getConnectionDirection1() != null ? new EnumModificationEmbedded<>(branchModificationInfos.getConnectionDirection1()) : null; + this.connectionDirection2 = branchModificationInfos.getConnectionDirection2() != null ? new EnumModificationEmbedded<>(branchModificationInfos.getConnectionDirection2()) : null; + this.connectionPosition1 = branchModificationInfos.getConnectionPosition1() != null ? new IntegerModificationEmbedded(branchModificationInfos.getConnectionPosition1()) : null; + this.connectionPosition2 = branchModificationInfos.getConnectionPosition2() != null ? new IntegerModificationEmbedded(branchModificationInfos.getConnectionPosition2()) : null; + this.terminal1Connected = branchModificationInfos.getTerminal1Connected() != null ? new BooleanModificationEmbedded(branchModificationInfos.getTerminal1Connected()) : null; + this.terminal2Connected = branchModificationInfos.getTerminal2Connected() != null ? new BooleanModificationEmbedded(branchModificationInfos.getTerminal2Connected()) : null; } } diff --git a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/LineModificationEntity.java b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/LineModificationEntity.java index a7f79a584..da4d92024 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/LineModificationEntity.java +++ b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/LineModificationEntity.java @@ -88,8 +88,18 @@ public LineModificationInfos toModificationInfos() { .activated(getActivated()) .equipmentId(getEquipmentId()) .equipmentName(AttributeModification.toAttributeModification(getEquipmentNameValue(), getEquipmentNameOp())) - .connected1(toAttributeModification(getConnected1())) - .connected2(toAttributeModification(getConnected2())) + .voltageLevelId1(toAttributeModification(getVoltageLevelId1())) + .voltageLevelId2(toAttributeModification(getVoltageLevelId2())) + .busOrBusbarSectionId1(toAttributeModification(getBusOrBusbarSectionId1())) + .busOrBusbarSectionId2(toAttributeModification(getBusOrBusbarSectionId2())) + .connectionName1(toAttributeModification(getConnectionName1())) + .connectionName2(toAttributeModification(getConnectionName2())) + .connectionDirection1(toAttributeModification(getConnectionDirection1())) + .connectionDirection2(toAttributeModification(getConnectionDirection2())) + .connectionPosition1(toAttributeModification(getConnectionPosition1())) + .connectionPosition2(toAttributeModification(getConnectionPosition2())) + .terminal1Connected(toAttributeModification(getTerminal1Connected())) + .terminal2Connected(toAttributeModification(getTerminal2Connected())) .r(toAttributeModification(getR())) .x(toAttributeModification(getX())) .g1(toAttributeModification(getG1())) diff --git a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/TwoWindingsTransformerModificationEntity.java b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/TwoWindingsTransformerModificationEntity.java index 8a96f8b51..95e106e2f 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/TwoWindingsTransformerModificationEntity.java +++ b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/TwoWindingsTransformerModificationEntity.java @@ -355,8 +355,18 @@ public TwoWindingsTransformerModificationInfos toModificationInfos() { .activated(getActivated()) .equipmentId(getEquipmentId()) .equipmentName(AttributeModification.toAttributeModification(getEquipmentNameValue(), getEquipmentNameOp())) - .connected1(toAttributeModification(getConnected1())) - .connected2(toAttributeModification(getConnected2())) + .voltageLevelId1(toAttributeModification(getVoltageLevelId1())) + .voltageLevelId2(toAttributeModification(getVoltageLevelId2())) + .busOrBusbarSectionId1(toAttributeModification(getBusOrBusbarSectionId1())) + .busOrBusbarSectionId2(toAttributeModification(getBusOrBusbarSectionId2())) + .connectionName1(toAttributeModification(getConnectionName1())) + .connectionName2(toAttributeModification(getConnectionName2())) + .connectionDirection1(toAttributeModification(getConnectionDirection1())) + .connectionDirection2(toAttributeModification(getConnectionDirection2())) + .connectionPosition1(toAttributeModification(getConnectionPosition1())) + .connectionPosition2(toAttributeModification(getConnectionPosition2())) + .terminal1Connected(toAttributeModification(getTerminal1Connected())) + .terminal2Connected(toAttributeModification(getTerminal2Connected())) .r(AttributeModification.toAttributeModification(getR())) .x(AttributeModification.toAttributeModification(getX())) .g(AttributeModification.toAttributeModification(getG())) diff --git a/src/main/java/org/gridsuite/modification/server/modifications/AbstractBranchModification.java b/src/main/java/org/gridsuite/modification/server/modifications/AbstractBranchModification.java index 1b69f73ed..a3305ef26 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/AbstractBranchModification.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/AbstractBranchModification.java @@ -10,6 +10,8 @@ import com.powsybl.commons.report.ReportNode; import com.powsybl.commons.report.TypedValue; import com.powsybl.iidm.network.*; +import com.powsybl.iidm.network.extensions.ConnectablePosition; +import com.powsybl.iidm.network.extensions.ConnectablePositionAdder; import org.gridsuite.modification.server.NetworkModificationException; import org.gridsuite.modification.server.dto.BranchModificationInfos; import org.gridsuite.modification.server.dto.CurrentLimitsModificationInfos; @@ -48,6 +50,8 @@ protected void modifyBranch(Branch branch, BranchModificationInfos branchModi branch.setName(branchModificationInfos.getEquipmentName().getValue()); } + modifyBranchConnectivityAttributes(branchModificationInfos, branch, subReportNode); + if (characteristicsModified(branchModificationInfos)) { modifyCharacteristics(branch, branchModificationInfos, subReportNode); } @@ -78,13 +82,13 @@ protected void modifyBranch(Branch branch, BranchModificationInfos branchModi private void updateConnections(Branch branch, BranchModificationInfos branchModificationInfos) { List errorSides = new ArrayList<>(); List errorTypes = new ArrayList<>(); - if (branchModificationInfos.getConnected1() != null && !updateConnection(branch, TwoSides.ONE, modificationInfos.getConnected1().getValue())) { + if (branchModificationInfos.getTerminal1Connected() != null && !updateConnection(branch, TwoSides.ONE, modificationInfos.getTerminal1Connected().getValue())) { errorSides.add(TwoSides.ONE); - errorTypes.add(Boolean.TRUE.equals(modificationInfos.getConnected1().getValue()) ? "connect" : "disconnect"); + errorTypes.add(Boolean.TRUE.equals(modificationInfos.getTerminal1Connected().getValue()) ? "connect" : "disconnect"); } - if (branchModificationInfos.getConnected2() != null && !updateConnection(branch, TwoSides.TWO, modificationInfos.getConnected2().getValue())) { + if (branchModificationInfos.getTerminal2Connected() != null && !updateConnection(branch, TwoSides.TWO, modificationInfos.getTerminal2Connected().getValue())) { errorSides.add(TwoSides.TWO); - errorTypes.add(Boolean.TRUE.equals(modificationInfos.getConnected2().getValue()) ? "connect" : "disconnect"); + errorTypes.add(Boolean.TRUE.equals(modificationInfos.getTerminal2Connected().getValue()) ? "connect" : "disconnect"); } if (!errorSides.isEmpty()) { throw new NetworkModificationException(BRANCH_MODIFICATION_ERROR, @@ -219,4 +223,11 @@ protected boolean characteristicsModified(BranchModificationInfos branchModifica protected abstract void modifyCharacteristics(Branch branch, BranchModificationInfos branchModificationInfos, ReportNode subReportNode); + + private ReportNode modifyBranchConnectivityAttributes(BranchModificationInfos branchModificationInfos, + Branch branch, ReportNode subReportNode) { + ConnectablePosition connectablePosition = (ConnectablePosition) branch.getExtension(ConnectablePosition.class); + ConnectablePositionAdder connectablePositionAdder = branch.newExtension(ConnectablePositionAdder.class); + return ModificationUtils.getInstance().modifyBranchConnectivityAttributes(connectablePosition, connectablePositionAdder, branch, branchModificationInfos, subReportNode); + } } diff --git a/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java b/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java index 02a6b04b5..92d4e588a 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java @@ -54,6 +54,7 @@ public final class ModificationUtils { public static final String CONNECTION_NAME_FIELD_NAME = "Connection name"; public static final String CONNECTION_DIRECTION_FIELD_NAME = "Connection direction"; public static final String CONNECTION_POSITION_FIELD_NAME = "Connection position"; + public static final String NOT_EXIST_IN_NETWORK = " does not exist in network"; private ModificationUtils() { } @@ -89,7 +90,7 @@ Line getLine(Network network, String lineId) { Battery getBattery(Network network, String batteryId) { Battery battery = network.getBattery(batteryId); if (battery == null) { - throw new NetworkModificationException(BATTERY_NOT_FOUND, "Battery " + batteryId + " does not exist in network"); + throw new NetworkModificationException(BATTERY_NOT_FOUND, "Battery " + batteryId + NOT_EXIST_IN_NETWORK); } return battery; } @@ -97,7 +98,7 @@ Battery getBattery(Network network, String batteryId) { Generator getGenerator(Network network, String generatorId) { Generator generator = network.getGenerator(generatorId); if (generator == null) { - throw new NetworkModificationException(GENERATOR_NOT_FOUND, "Generator " + generatorId + " does not exist in network"); + throw new NetworkModificationException(GENERATOR_NOT_FOUND, "Generator " + generatorId + NOT_EXIST_IN_NETWORK); } return generator; } @@ -105,7 +106,7 @@ Generator getGenerator(Network network, String generatorId) { VscConverterStation getVscConverterStation(Network network, String converterStationId) { VscConverterStation vscConverterStation = network.getVscConverterStation(converterStationId); if (vscConverterStation == null) { - throw new NetworkModificationException(VSC_CONVERTER_STATION_NOT_FOUND, "Vsc converter station " + converterStationId + " does not exist in network"); + throw new NetworkModificationException(VSC_CONVERTER_STATION_NOT_FOUND, "Vsc converter station " + converterStationId + NOT_EXIST_IN_NETWORK); } return vscConverterStation; } @@ -114,7 +115,7 @@ VscConverterStation getVscConverterStation(Network network, String converterStat HvdcLine getHvdcLine(Network network, String hvdcLineId) { HvdcLine hvdcLine = network.getHvdcLine(hvdcLineId); if (hvdcLine == null) { - throw new NetworkModificationException(HVDC_LINE_NOT_FOUND, "Hvdc line " + hvdcLineId + " does not exist in network"); + throw new NetworkModificationException(HVDC_LINE_NOT_FOUND, "Hvdc line " + hvdcLineId + NOT_EXIST_IN_NETWORK); } return hvdcLine; } @@ -493,10 +494,7 @@ public ReportNode reportModifications(ReportNode reportNode, List re for (Map.Entry valueEntry : report.getValues().entrySet()) { reportNodeAdder.withUntypedValue(valueEntry.getKey(), valueEntry.getValue().toString()); } - TypedValue severity = report.getValue(ReportConstants.SEVERITY_KEY).orElse(null); - if (severity != null) { - reportNodeAdder.withSeverity(severity); - } + report.getValue(ReportConstants.SEVERITY_KEY).ifPresent(reportNodeAdder::withSeverity); reportNodeAdder.add(); } } @@ -601,120 +599,235 @@ public void disconnectCreatedInjection(InjectionCreationInfos modificationInfos, } public ReportNode modifyInjectionConnectivityAttributes(ConnectablePosition connectablePosition, - ConnectablePositionAdder connectablePositionAdder, - Injection injection, - InjectionModificationInfos modificationInfos, - ReportNode connectivityReports) { + ConnectablePositionAdder connectablePositionAdder, + Injection injection, + InjectionModificationInfos modificationInfos, + ReportNode connectivityReports) { List reports = new ArrayList<>(); - if (modificationInfos.getVoltageLevelId() == null || modificationInfos.getBusOrBusbarSectionId() == null) { - return ReportNode.newRootReportNode() + if (isVoltageOrBusbarIdMissing(modificationInfos.getVoltageLevelId(), modificationInfos.getBusOrBusbarSectionId(), modificationInfos.getEquipmentId(), reports)) { + return reports.get(0); + } + processConnectivityPosition(connectablePosition, connectablePositionAdder, modificationInfos, reports, false); + modifyConnection(modificationInfos.getTerminalConnected(), injection, injection.getTerminal(), reports); + + return reportModifications(connectivityReports, reports, "ConnectivityModified", CONNECTIVITY); + } + + public ReportNode modifyBranchConnectivityAttributes(ConnectablePosition connectablePosition, + ConnectablePositionAdder connectablePositionAdder, + Branch branch, + BranchModificationInfos modificationInfos, + ReportNode connectivityReports) { + List reports = new ArrayList<>(); + if (isVoltageOrBusbarIdMissing(modificationInfos.getVoltageLevelId1(), modificationInfos.getBusOrBusbarSectionId1(), modificationInfos.getEquipmentId(), reports) || + isVoltageOrBusbarIdMissing(modificationInfos.getVoltageLevelId2(), modificationInfos.getBusOrBusbarSectionId2(), modificationInfos.getEquipmentId(), reports)) { + return reports.get(0); + } + + processConnectivityPosition(connectablePosition, connectablePositionAdder, modificationInfos, reports, true); + modifyConnection(modificationInfos.getTerminal1Connected(), branch, branch.getTerminal1(), reports); + modifyConnection(modificationInfos.getTerminal2Connected(), branch, branch.getTerminal2(), reports); + + return reportModifications(connectivityReports, reports, "ConnectivityModified", CONNECTIVITY); + } + + private boolean isVoltageOrBusbarIdMissing(AttributeModification voltageLevelId, AttributeModification busbarSectionId, String equipmentId, List reports) { + if (voltageLevelId == null || busbarSectionId == null) { + reports.add(ReportNode.newRootReportNode() .withMessageTemplate("VoltageLevelOrBusbarSectionNotFound", "Voltage level id or Bus bar section id of equipment id=${id} not found") - .withUntypedValue("id", modificationInfos.getEquipmentId()) + .withUntypedValue("id", equipmentId) .withSeverity(TypedValue.WARN_SEVERITY) - .build(); + .build()); + return true; } + return false; + } + + private void processConnectivityPosition(ConnectablePosition connectablePosition, + ConnectablePositionAdder connectablePositionAdder, + Object modificationInfos, + List reports, + boolean isBranch) { if (connectablePosition != null) { - modifyExistingConnectivityPosition(connectablePosition, modificationInfos, reports); + modifyExistingConnectivityPosition(connectablePosition, modificationInfos, reports, isBranch); } else { - createNewConnectivityPosition(connectablePositionAdder, modificationInfos, reports); + createNewConnectivityPosition(connectablePositionAdder, modificationInfos, reports, isBranch); } - modifyInjectionConnection(modificationInfos, injection, reports); - return reportModifications(connectivityReports, reports, "ConnectivityModified", CONNECTIVITY); } private void modifyExistingConnectivityPosition(ConnectablePosition connectablePosition, - InjectionModificationInfos modificationInfos, - List reports) { - ConnectablePosition.Feeder feeder = connectablePosition.getFeeder(); - ReportNode connectionNameReport = applyElementaryModificationsAndReturnReport( - feeder::setName, + Object modificationInfos, + List reports, + boolean isBranch) { + if (isBranch) { + modifyFeeder(connectablePosition.getFeeder1(), modificationInfos, reports, 1); + modifyFeeder(connectablePosition.getFeeder2(), modificationInfos, reports, 2); + } else { + modifyFeeder(connectablePosition.getFeeder(), modificationInfos, reports, 0); + } + } + + private void createNewConnectivityPosition(ConnectablePositionAdder adder, + Object modificationInfos, + List reports, + boolean isBranch) { + if (isBranch) { + ConnectablePositionAdder.FeederAdder feeder1 = adder.newFeeder1(); + ConnectablePositionAdder.FeederAdder feeder2 = adder.newFeeder2(); + modifyFeederAdder(feeder1, modificationInfos, reports, 1); + modifyFeederAdder(feeder2, modificationInfos, reports, 2); + } else { + ConnectablePositionAdder.FeederAdder feeder = adder.newFeeder(); + modifyFeederAdder(feeder, modificationInfos, reports, 0); + } + adder.add(); + } + + private void modifyFeeder(ConnectablePosition.Feeder feeder, + Object modificationInfos, + List reports, + int feederNumber) { + applyModifications(feeder, modificationInfos, reports, feederNumber); + } + + private void applyModifications(ConnectablePosition.Feeder feeder, + Object modificationInfos, + List reports, + int feederNumber) { + ReportNode connectionNameReport = applyElementaryModificationsAndReturnReport(feeder::setName, feeder.getName()::get, - modificationInfos.getConnectionName(), - CONNECTION_NAME_FIELD_NAME); + getConnectionName(modificationInfos, feederNumber), + getConnectionNameField(feederNumber)); if (connectionNameReport != null) { reports.add(connectionNameReport); } - ReportNode connectionDirectionReport = applyElementaryModificationsAndReturnReport( - feeder::setDirection, + ReportNode connectionDirectionReport = applyElementaryModificationsAndReturnReport(feeder::setDirection, feeder::getDirection, - modificationInfos.getConnectionDirection(), - CONNECTION_DIRECTION_FIELD_NAME); + getConnectionDirection(modificationInfos, feederNumber), + getConnectionDirectionField(feederNumber)); if (connectionDirectionReport != null) { reports.add(connectionDirectionReport); } - ReportNode connectionPositionReport = applyElementaryModificationsAndReturnReport( - feeder::setOrder, + ReportNode connectionPositionReport = applyElementaryModificationsAndReturnReport(feeder::setOrder, feeder.getOrder()::get, - modificationInfos.getConnectionPosition(), - CONNECTION_POSITION_FIELD_NAME); + getConnectionPosition(modificationInfos, feederNumber), + getConnectionPositionField(feederNumber)); if (connectionPositionReport != null) { reports.add(connectionPositionReport); } } - private void createNewConnectivityPosition(ConnectablePositionAdder adder, - InjectionModificationInfos modificationInfos, - List reports) { - ConnectablePositionAdder.FeederAdder feeder = adder.newFeeder(); - ReportNode connectionNameReport = applyElementaryModificationsAndReturnReport( - feeder::withName, + private void modifyFeederAdder(ConnectablePositionAdder.FeederAdder feeder, + Object modificationInfos, + List reports, + int feederNumber) { + ReportNode connectionNameReport = applyElementaryModificationsAndReturnReport(feeder::withName, () -> null, - modificationInfos.getConnectionName(), - CONNECTION_NAME_FIELD_NAME); + getConnectionName(modificationInfos, feederNumber), + getConnectionNameField(feederNumber)); if (connectionNameReport != null) { reports.add(connectionNameReport); } - - ReportNode connectionDirectionReport = applyElementaryModificationsAndReturnReport( - feeder::withDirection, + ReportNode connectionDirectionReport = applyElementaryModificationsAndReturnReport(feeder::withDirection, () -> null, - modificationInfos.getConnectionDirection(), - CONNECTION_DIRECTION_FIELD_NAME); + getConnectionDirection(modificationInfos, feederNumber), + getConnectionDirectionField(feederNumber)); if (connectionDirectionReport != null) { reports.add(connectionDirectionReport); } - - ReportNode connectionPositionReport = applyElementaryModificationsAndReturnReport( - feeder::withOrder, + ReportNode connectionPositionReport = applyElementaryModificationsAndReturnReport(feeder::withOrder, () -> null, - modificationInfos.getConnectionPosition(), - CONNECTION_POSITION_FIELD_NAME); + getConnectionPosition(modificationInfos, feederNumber), + getConnectionPositionField(feederNumber)); if (connectionPositionReport != null) { reports.add(connectionPositionReport); } - if (connectionNameReport != null || connectionDirectionReport != null || connectionPositionReport != null) { - adder.add(); + feeder.add(); } } - public void modifyInjectionConnection(InjectionModificationInfos modificationInfos, Injection injection, List subReportNode) { - if (modificationInfos.getTerminalConnected() != null && injection != null) { - if (isInjectionConnected(injection) && Boolean.FALSE.equals(modificationInfos.getTerminalConnected().getValue())) { - injection.getTerminal().disconnect(); - if (isInjectionConnected(injection)) { - throw new NetworkModificationException(INJECTION_MODIFICATION_ERROR, - String.format("Could not disconnect equipment '%s'", injection.getId())); - } - subReportNode.add(ReportNode.newRootReportNode() - .withMessageTemplate("equipmentDisconnected", " Equipment with id=${id} disconnected") - .withUntypedValue("id", modificationInfos.getEquipmentId()) - .withSeverity(TypedValue.INFO_SEVERITY) - .build()); - } else if (!isInjectionConnected(injection) && Boolean.TRUE.equals(modificationInfos.getTerminalConnected().getValue())) { - injection.getTerminal().connect(); - if (!isInjectionConnected(injection)) { - throw new NetworkModificationException(INJECTION_MODIFICATION_ERROR, - String.format("Could not connect equipment '%s'", injection.getId())); - } - subReportNode.add(ReportNode.newRootReportNode() - .withMessageTemplate("equipmentConnected", " Equipment with id=${id} connected") - .withUntypedValue("id", modificationInfos.getEquipmentId()) - .withSeverity(TypedValue.INFO_SEVERITY) - .build()); - } + private T getConnectionDetail(Object modificationInfos, int feederNumber, + Function branchFunc1, + Function branchFunc2, + Function injectionFunc) { + if (modificationInfos instanceof BranchModificationInfos branchInfo) { + return feederNumber == 1 ? branchFunc1.apply(branchInfo) : branchFunc2.apply(branchInfo); + } else if (modificationInfos instanceof InjectionModificationInfos injectionInfo) { + return injectionFunc.apply(injectionInfo); } + return null; + } + + private String getConnectionFieldName(int feederNumber, String baseFieldName) { + return switch (feederNumber) { + case 0 -> baseFieldName; + case 1 -> baseFieldName + " 1"; + case 2 -> baseFieldName + " 2"; + default -> ""; + }; + } + + private AttributeModification getConnectionName(Object modificationInfos, int feederNumber) { + return getConnectionDetail(modificationInfos, feederNumber, + BranchModificationInfos::getConnectionName1, BranchModificationInfos::getConnectionName2, + InjectionModificationInfos::getConnectionName); + } + + private String getConnectionNameField(int feederNumber) { + return getConnectionFieldName(feederNumber, CONNECTION_NAME_FIELD_NAME); + } + + private String getConnectionDirectionField(int feederNumber) { + return getConnectionFieldName(feederNumber, CONNECTION_DIRECTION_FIELD_NAME); + } + + private String getConnectionPositionField(int feederNumber) { + return getConnectionFieldName(feederNumber, CONNECTION_POSITION_FIELD_NAME); + } + + private AttributeModification getConnectionDirection(Object modificationInfos, int feederNumber) { + return getConnectionDetail(modificationInfos, feederNumber, + BranchModificationInfos::getConnectionDirection1, BranchModificationInfos::getConnectionDirection2, + InjectionModificationInfos::getConnectionDirection); + } + + private AttributeModification getConnectionPosition(Object modificationInfos, int feederNumber) { + return getConnectionDetail(modificationInfos, feederNumber, + BranchModificationInfos::getConnectionPosition1, BranchModificationInfos::getConnectionPosition2, + InjectionModificationInfos::getConnectionPosition); + } + + private void modifyConnection(AttributeModification terminalConnected, Identifiable equipment, Terminal terminal, List reports) { + if (terminalConnected == null || equipment == null) { + return; + } + + boolean isConnected = terminal.isConnected(); + if (isConnected && Boolean.FALSE.equals(terminalConnected.getValue())) { + terminal.disconnect(); + validateConnectionChange(!terminal.isConnected(), equipment, "disconnect", reports); + } else if (!isConnected && Boolean.TRUE.equals(terminalConnected.getValue())) { + terminal.connect(); + validateConnectionChange(terminal.isConnected(), equipment, "connect", reports); + } + } + + private void validateConnectionChange(boolean success, Identifiable equipment, String action, List reports) { + if (!success) { + throw new NetworkModificationException(equipment instanceof Branch ? BRANCH_MODIFICATION_ERROR : INJECTION_MODIFICATION_ERROR, + String.format("Could not %s equipment '%s'", action, equipment.getId())); + } + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate("equipment" + capitalize(action), String.format("Equipment with id=${id} %sed", action)) + .withUntypedValue("id", equipment.getId()) + .withSeverity(TypedValue.INFO_SEVERITY) + .build()); + } + + private String capitalize(String input) { + return input.substring(0, 1).toUpperCase() + input.substring(1); } public void disconnectBranch(BranchCreationInfos modificationInfos, Branch branch, ReportNode subReportNode) { @@ -742,38 +855,23 @@ public Identifiable getEquipmentByIdentifiableType(Network network, Identifia return null; } - switch (type) { - case HVDC_LINE: - return network.getHvdcLine(equipmentId); - case LINE: - return network.getLine(equipmentId); - case TWO_WINDINGS_TRANSFORMER: - return network.getTwoWindingsTransformer(equipmentId); - case THREE_WINDINGS_TRANSFORMER: - return network.getThreeWindingsTransformer(equipmentId); - case GENERATOR: - return network.getGenerator(equipmentId); - case LOAD: - return network.getLoad(equipmentId); - case BATTERY: - return network.getBattery(equipmentId); - case SHUNT_COMPENSATOR: - return network.getShuntCompensator(equipmentId); - case STATIC_VAR_COMPENSATOR: - return network.getStaticVarCompensator(equipmentId); - case DANGLING_LINE: - return network.getDanglingLine(equipmentId); - case HVDC_CONVERTER_STATION: - return network.getHvdcConverterStation(equipmentId); - case SUBSTATION: - return network.getSubstation(equipmentId); - case VOLTAGE_LEVEL: - return network.getVoltageLevel(equipmentId); - case BUSBAR_SECTION: - return network.getBusbarSection(equipmentId); - default: - return null; - } + return switch (type) { + case HVDC_LINE -> network.getHvdcLine(equipmentId); + case LINE -> network.getLine(equipmentId); + case TWO_WINDINGS_TRANSFORMER -> network.getTwoWindingsTransformer(equipmentId); + case THREE_WINDINGS_TRANSFORMER -> network.getThreeWindingsTransformer(equipmentId); + case GENERATOR -> network.getGenerator(equipmentId); + case LOAD -> network.getLoad(equipmentId); + case BATTERY -> network.getBattery(equipmentId); + case SHUNT_COMPENSATOR -> network.getShuntCompensator(equipmentId); + case STATIC_VAR_COMPENSATOR -> network.getStaticVarCompensator(equipmentId); + case DANGLING_LINE -> network.getDanglingLine(equipmentId); + case HVDC_CONVERTER_STATION -> network.getHvdcConverterStation(equipmentId); + case SUBSTATION -> network.getSubstation(equipmentId); + case VOLTAGE_LEVEL -> network.getVoltageLevel(equipmentId); + case BUSBAR_SECTION -> network.getBusbarSection(equipmentId); + default -> null; + }; } public void setCurrentLimits(CurrentLimitsInfos currentLimitsInfos, CurrentLimitsAdder limitsAdder) { @@ -1266,10 +1364,7 @@ public static void insertReportNode(ReportNode parent, ReportNode child) { for (Map.Entry valueEntry : child.getValues().entrySet()) { adder.withUntypedValue(valueEntry.getKey(), valueEntry.getValue().toString()); } - TypedValue severity = child.getValue(ReportConstants.SEVERITY_KEY).orElse(null); - if (severity != null) { - adder.withSeverity(severity); - } + child.getValue(ReportConstants.SEVERITY_KEY).ifPresent(adder::withSeverity); ReportNode insertedChild = adder.add(); if (child.getChildren() != null) { child.getChildren().forEach(grandChild -> insertReportNode(insertedChild, grandChild)); diff --git a/src/main/resources/db/changelog/changesets/changelog_20240904T211456Z.xml b/src/main/resources/db/changelog/changesets/changelog_20240904T211456Z.xml new file mode 100644 index 000000000..5d6cf56f0 --- /dev/null +++ b/src/main/resources/db/changelog/changesets/changelog_20240904T211456Z.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 6f9f44d4e..32b8d57e2 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -305,4 +305,7 @@ databaseChangeLog: relativeToChangelogFile: true - include: file: changesets/changelog_20240829T071248Z.xml + relativeToChangelogFile: true + - include: + file: changesets/changelog_20240904T211456Z.xml relativeToChangelogFile: true \ No newline at end of file diff --git a/src/test/java/org/gridsuite/modification/server/modifications/LineModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/LineModificationTest.java index 165d082e4..69af786b8 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/LineModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/LineModificationTest.java @@ -11,6 +11,7 @@ import com.powsybl.iidm.network.Line; import com.powsybl.iidm.network.LoadingLimits.TemporaryLimit; import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.extensions.ConnectablePosition; import lombok.SneakyThrows; import org.gridsuite.modification.server.NetworkModificationException; import org.gridsuite.modification.server.dto.*; @@ -51,6 +52,16 @@ protected ModificationInfos buildModification() { .stashed(false) .equipmentId("line1") .equipmentName(new AttributeModification<>("LineModified", OperationType.SET)) + .voltageLevelId1(new AttributeModification<>("v1", OperationType.SET)) + .voltageLevelId2(new AttributeModification<>("v4", OperationType.SET)) + .busOrBusbarSectionId1(new AttributeModification<>("1B", OperationType.SET)) + .busOrBusbarSectionId2(new AttributeModification<>("2B", OperationType.SET)) + .connectionName1(new AttributeModification<>("cn1Line1", OperationType.SET)) + .connectionName2(new AttributeModification<>("cn2Line1", OperationType.SET)) + .connectionDirection1(new AttributeModification<>(ConnectablePosition.Direction.TOP, OperationType.SET)) + .connectionDirection2(new AttributeModification<>(ConnectablePosition.Direction.TOP, OperationType.SET)) + .connectionPosition1(new AttributeModification<>(1, OperationType.SET)) + .connectionPosition2(new AttributeModification<>(1, OperationType.SET)) .currentLimits1(CurrentLimitsModificationInfos.builder() .permanentLimit(12.0) .temporaryLimits(List.of(CurrentTemporaryLimitModificationInfos.builder() @@ -378,8 +389,8 @@ public void testConnection() throws Exception { private void changeLineConnectionState(Line existingEquipment, boolean expectedState) throws Exception { LineModificationInfos modificationInfos = (LineModificationInfos) buildModification(); - modificationInfos.setConnected1(new AttributeModification<>(expectedState, OperationType.SET)); - modificationInfos.setConnected2(new AttributeModification<>(expectedState, OperationType.SET)); + modificationInfos.setTerminal1Connected(new AttributeModification<>(expectedState, OperationType.SET)); + modificationInfos.setTerminal2Connected(new AttributeModification<>(expectedState, OperationType.SET)); if (expectedState) { if (existingEquipment.getTerminal1().isConnected()) { diff --git a/src/test/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModificationTest.java index 7ec3a0df4..efd3a20a0 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModificationTest.java @@ -15,6 +15,7 @@ import com.powsybl.iidm.network.TwoSides; import com.powsybl.iidm.network.TwoWindingsTransformer; +import com.powsybl.iidm.network.extensions.ConnectablePosition; import lombok.SneakyThrows; import org.gridsuite.modification.server.NetworkModificationException; import org.gridsuite.modification.server.dto.*; @@ -79,6 +80,16 @@ protected ModificationInfos buildModification() { .modificationType(TemporaryLimitModificationType.ADDED) .build())) .build()) + .voltageLevelId1(new AttributeModification<>("v1", OperationType.SET)) + .voltageLevelId2(new AttributeModification<>("v2", OperationType.SET)) + .busOrBusbarSectionId1(new AttributeModification<>("1B", OperationType.SET)) + .busOrBusbarSectionId2(new AttributeModification<>("2B", OperationType.SET)) + .connectionName1(new AttributeModification<>("trf1", OperationType.SET)) + .connectionName2(new AttributeModification<>("trf1", OperationType.SET)) + .connectionDirection1(new AttributeModification<>(ConnectablePosition.Direction.TOP, OperationType.SET)) + .connectionDirection2(new AttributeModification<>(ConnectablePosition.Direction.TOP, OperationType.SET)) + .connectionPosition1(new AttributeModification<>(1, OperationType.SET)) + .connectionPosition2(new AttributeModification<>(2, OperationType.SET)) .ratioTapChanger(RatioTapChangerModificationInfos.builder() .enabled(new AttributeModification<>(true, OperationType.SET)) .loadTapChangingCapabilities(new AttributeModification<>(true, OperationType.SET)) @@ -603,8 +614,8 @@ private void changeConnectionState(TwoWindingsTransformer existingEquipment, Two TwoWindingsTransformerModificationInfos.builder() .stashed(false) .equipmentId(existingEquipment.getId()) - .connected1(side == TwoSides.ONE ? new AttributeModification<>(expectedState, OperationType.SET) : null) - .connected2(side == TwoSides.TWO ? new AttributeModification<>(expectedState, OperationType.SET) : null) + .terminal1Connected(side == TwoSides.ONE ? new AttributeModification<>(expectedState, OperationType.SET) : null) + .terminal2Connected(side == TwoSides.TWO ? new AttributeModification<>(expectedState, OperationType.SET) : null) .build(); String modificationInfosJson = mapper.writeValueAsString(modificationInfos); MvcResult mvcResult = mockMvc.perform(post(getNetworkModificationUri()).content(modificationInfosJson).contentType(MediaType.APPLICATION_JSON))