From da0b580cb212b7e8e71002b4ccf98adbadc0131d Mon Sep 17 00:00:00 2001 From: Ghazoua Rehili Date: Mon, 9 Dec 2024 17:01:58 +0100 Subject: [PATCH] add hvdc lcc creation entity (#3) Signed-off-by: Rehili Ghazwa --- .../modification/ModificationType.java | 4 +- .../NetworkModificationException.java | 2 + .../dto/LccConverterStationCreationInfos.java | 53 ++++ .../modification/dto/LccCreationInfos.java | 69 +++++ .../modification/dto/ModificationInfos.java | 2 + .../modifications/LccCreation.java | 268 ++++++++++++++++++ .../modification/utils/ModificationUtils.java | 8 + .../LccCreationInBusBreakerTest.java | 123 ++++++++ .../LccCreationInNodeBreakerTest.java | 146 ++++++++++ 9 files changed, 674 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/gridsuite/modification/dto/LccConverterStationCreationInfos.java create mode 100644 src/main/java/org/gridsuite/modification/dto/LccCreationInfos.java create mode 100644 src/main/java/org/gridsuite/modification/modifications/LccCreation.java create mode 100644 src/test/java/org/gridsuite/modification/modifications/LccCreationInBusBreakerTest.java create mode 100644 src/test/java/org/gridsuite/modification/modifications/LccCreationInNodeBreakerTest.java diff --git a/src/main/java/org/gridsuite/modification/ModificationType.java b/src/main/java/org/gridsuite/modification/ModificationType.java index efba552..8b42bdc 100644 --- a/src/main/java/org/gridsuite/modification/ModificationType.java +++ b/src/main/java/org/gridsuite/modification/ModificationType.java @@ -52,7 +52,9 @@ public enum ModificationType { TABULAR_CREATION(PreloadingStrategy.COLLECTION), BY_FORMULA_MODIFICATION(PreloadingStrategy.COLLECTION), MODIFICATION_BY_ASSIGNMENT(PreloadingStrategy.COLLECTION), - COMPOSITE_MODIFICATION(PreloadingStrategy.COLLECTION); + COMPOSITE_MODIFICATION(PreloadingStrategy.COLLECTION), + LCC_CONVERTER_STATION_CREATION(PreloadingStrategy.NONE), + LCC_CREATION(PreloadingStrategy.NONE); private final PreloadingStrategy strategy; diff --git a/src/main/java/org/gridsuite/modification/NetworkModificationException.java b/src/main/java/org/gridsuite/modification/NetworkModificationException.java index 3c0800d..67255b9 100644 --- a/src/main/java/org/gridsuite/modification/NetworkModificationException.java +++ b/src/main/java/org/gridsuite/modification/NetworkModificationException.java @@ -112,8 +112,10 @@ public enum Type { TABULAR_CREATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), CREATE_VSC_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), MODIFY_VSC_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), + CREATE_LCC_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), HVDC_LINE_ALREADY_EXISTS(HttpStatus.BAD_REQUEST), VSC_CONVERTER_STATION_NOT_FOUND(HttpStatus.NOT_FOUND), + LCC_CONVERTER_STATION_NOT_FOUND(HttpStatus.NOT_FOUND), CREATE_CONVERTER_STATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), MODIFY_CONVERTER_STATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), BY_FORMULA_MODIFICATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), diff --git a/src/main/java/org/gridsuite/modification/dto/LccConverterStationCreationInfos.java b/src/main/java/org/gridsuite/modification/dto/LccConverterStationCreationInfos.java new file mode 100644 index 0000000..7aff21f --- /dev/null +++ b/src/main/java/org/gridsuite/modification/dto/LccConverterStationCreationInfos.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.gridsuite.modification.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import lombok.experimental.SuperBuilder; +import org.gridsuite.modification.dto.annotation.ModificationErrorTypeName; + +import java.util.List; + +/** + * @author Ghazwa Rehili + */ + +@SuperBuilder +@NoArgsConstructor +@Getter +@Setter +@ToString(callSuper = true) +@Schema(description = "Lcc converter station creation") +@JsonTypeName("LCC_CONVERTER_STATION_CREATION") +@ModificationErrorTypeName("LCC_CREATE_CONVERTER_STATION_ERROR") +public class LccConverterStationCreationInfos extends InjectionCreationInfos { + @Builder + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class ShuntCompensatorInfos { + private String id; + private String name; + private Double maxQAtNominalV; + private Boolean connectedToHvdc; + } + + @Schema(description = "Loss Factor") + private Float lossFactor; + + @Schema(description = "Power Factor") + private Float powerFactor; + + @Schema(description = "LCC HVDC Converter Station Shunt Compensator") + @JsonInclude(JsonInclude.Include.NON_NULL) + private List shuntCompensatorsOnSide; +} diff --git a/src/main/java/org/gridsuite/modification/dto/LccCreationInfos.java b/src/main/java/org/gridsuite/modification/dto/LccCreationInfos.java new file mode 100644 index 0000000..ce72a9d --- /dev/null +++ b/src/main/java/org/gridsuite/modification/dto/LccCreationInfos.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.gridsuite.modification.dto; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.powsybl.commons.report.ReportNode; +import com.powsybl.iidm.network.HvdcLine; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.SuperBuilder; +import org.gridsuite.modification.dto.annotation.ModificationErrorTypeName; +import org.gridsuite.modification.modifications.AbstractModification; +import org.gridsuite.modification.modifications.LccCreation; + +/** + * @author Ghazwa Rehili + */ + +@SuperBuilder +@NoArgsConstructor +@Getter +@Setter +@ToString(callSuper = true) +@Schema(description = "LCC creation") +@JsonTypeName("LCC_CREATION") +@ModificationErrorTypeName("CREATE_LCC_ERROR") +public class LccCreationInfos extends EquipmentCreationInfos { + @Schema(description = "DC nominal voltage") + private Double nominalV; + + @Schema(description = "DC resistance") + private Double r; + + @Schema(description = "Maximum active power") + private Double maxP; + + @Schema(description = "Converters mode") + private HvdcLine.ConvertersMode convertersMode; + + @Schema(description = "Active power setpoint") + private Double activePowerSetpoint; + + @Schema(description = "Converter station 1") + private LccConverterStationCreationInfos converterStation1; + + @Schema(description = "Converter station 2") + private LccConverterStationCreationInfos converterStation2; + + @Override + public AbstractModification toModification() { + return new LccCreation(this); + } + + @Override + public ReportNode createSubReportNode(ReportNode reportNode) { + return reportNode.newReportNode() + .withMessageTemplate(getType().name(), "Lcc creation ${lccId}") + .withUntypedValue("lccId", getEquipmentId()) + .add(); + } +} diff --git a/src/main/java/org/gridsuite/modification/dto/ModificationInfos.java b/src/main/java/org/gridsuite/modification/dto/ModificationInfos.java index 3a56daf..fa06171 100644 --- a/src/main/java/org/gridsuite/modification/dto/ModificationInfos.java +++ b/src/main/java/org/gridsuite/modification/dto/ModificationInfos.java @@ -66,6 +66,8 @@ @JsonSubTypes.Type(value = GenerationDispatchInfos.class), @JsonSubTypes.Type(value = VoltageInitModificationInfos.class), @JsonSubTypes.Type(value = VscCreationInfos.class), + @JsonSubTypes.Type(value = LccCreationInfos.class), + @JsonSubTypes.Type(value = LccConverterStationCreationInfos.class), @JsonSubTypes.Type(value = ConverterStationCreationInfos.class), @JsonSubTypes.Type(value = TabularModificationInfos.class), @JsonSubTypes.Type(value = ByFormulaModificationInfos.class), diff --git a/src/main/java/org/gridsuite/modification/modifications/LccCreation.java b/src/main/java/org/gridsuite/modification/modifications/LccCreation.java new file mode 100644 index 0000000..e8b64c6 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/modifications/LccCreation.java @@ -0,0 +1,268 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.gridsuite.modification.modifications; + +import com.powsybl.commons.report.ReportNode; +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.*; +import org.apache.commons.lang3.StringUtils; +import org.gridsuite.modification.NetworkModificationException; +import org.gridsuite.modification.dto.LccConverterStationCreationInfos; +import org.gridsuite.modification.dto.LccCreationInfos; +import org.gridsuite.modification.utils.ModificationUtils; +import org.gridsuite.modification.utils.PropertiesUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import static org.gridsuite.modification.NetworkModificationException.Type.CREATE_LCC_ERROR; +import static org.gridsuite.modification.NetworkModificationException.Type.HVDC_LINE_ALREADY_EXISTS; +import static org.gridsuite.modification.utils.ModificationUtils.createInjectionInNodeBreaker; +import static org.gridsuite.modification.utils.ModificationUtils.reportInjectionCreationConnectivity; + +/** + * @author Rehili Ghazwa + */ + +public class LccCreation extends AbstractModification { + public static final String LCC_CHARACTERISTICS = "lccCharacteristics"; + public static final String FILTERS = "Filters"; + + public static final String LCC_SETPOINTS = "LccSetPoints"; + + public static final String EQUIPMENT_CONNECTED_TO_HVDC = "equipmentConnectedToHvdc"; + public static final String EQUIPMENT_NOT_CONNECTED_TO_HVDC = "equipmentNotConnectedToHvdc"; + + private final LccCreationInfos modificationInfos; + + public LccCreation(LccCreationInfos modificationInfos) { + this.modificationInfos = modificationInfos; + } + + @Override + public void check(Network network) throws NetworkModificationException { + if (network.getHvdcLine(modificationInfos.getEquipmentId()) != null) { + throw new NetworkModificationException(HVDC_LINE_ALREADY_EXISTS, modificationInfos.getEquipmentId()); + } + checkLccConverterStation(network, modificationInfos.getConverterStation1()); + checkLccConverterStation(network, modificationInfos.getConverterStation2()); + } + + private void checkLccConverterStation(Network network, LccConverterStationCreationInfos converterStation) { + if (converterStation == null) { + throw new NetworkModificationException(CREATE_LCC_ERROR, modificationInfos.getEquipmentId() + "Missing required converter station"); + } + if (converterStation.getPowerFactor() > 1) { + throw new NetworkModificationException(CREATE_LCC_ERROR, "Loss factor should be less or equal to 1"); + } + // check connectivity + ModificationUtils.getInstance().controlConnectivity(network, + converterStation.getVoltageLevelId(), + converterStation.getBusOrBusbarSectionId(), + converterStation.getConnectionPosition()); + } + + @Override + public void apply(Network network, ReportNode subReportNode) { + LccConverterStation converterStation1 = createConverterStation(network, modificationInfos.getConverterStation1(), subReportNode); + LccConverterStation converterStation2 = createConverterStation(network, modificationInfos.getConverterStation2(), subReportNode); + + HvdcLine hvdcLine = network.newHvdcLine() + .setId(modificationInfos.getEquipmentId()) + .setName(modificationInfos.getEquipmentName()) + .setNominalV(modificationInfos.getNominalV()) + .setR(modificationInfos.getR()) + .setMaxP(modificationInfos.getMaxP()) + .setActivePowerSetpoint(modificationInfos.getActivePowerSetpoint()) + .setConvertersMode(modificationInfos.getConvertersMode()) + .setConverterStationId1(converterStation1 != null ? converterStation1.getId() : null) + .setConverterStationId2(converterStation2 != null ? converterStation2.getId() : null) + .add(); + + subReportNode.newReportNode() + .withMessageTemplate("lccCreated", "New lcc with id=${id} created") + .withUntypedValue("id", modificationInfos.getEquipmentId()) + .withSeverity(TypedValue.INFO_SEVERITY) + .add(); + reportHvdcLineInfos(hvdcLine, subReportNode); + addReportConverterStationLcc(modificationInfos.getConverterStation1(), "Lcc Converter station 1", subReportNode); + addReportConverterStationLcc(modificationInfos.getConverterStation2(), "Lcc Converter station 2", subReportNode); + } + + @Override + public String getName() { + return "LCC_Creation"; + } + + private LccConverterStation createConverterStation(Network network, + LccConverterStationCreationInfos lccConverterStationCreationInfos, + ReportNode subReportNode) { + VoltageLevel voltageLevel = ModificationUtils.getInstance().getVoltageLevel(network, lccConverterStationCreationInfos.getVoltageLevelId()); + return voltageLevel.getTopologyKind() == TopologyKind.NODE_BREAKER ? + createConverterStationInNodeBreaker(network, voltageLevel, lccConverterStationCreationInfos, subReportNode) : + createConverterStationInBusBreaker(network, voltageLevel, lccConverterStationCreationInfos, subReportNode); + } + + private ShuntCompensatorAdder createShuntCompensatorInNodeBreaker(VoltageLevel voltageLevel, LccConverterStationCreationInfos.ShuntCompensatorInfos shuntCompensatorInfos) { + return voltageLevel.newShuntCompensator() + .setId(shuntCompensatorInfos.getId()) + .setName(shuntCompensatorInfos.getName()) + .setSectionCount(1) + .newLinearModel() + .setBPerSection((shuntCompensatorInfos.getMaxQAtNominalV()) / Math.pow(voltageLevel.getNominalV(), 2)) + .setMaximumSectionCount(1) + .add(); + } + + private void createShuntCompensatorInBusBreaker(VoltageLevel voltageLevel, Bus bus, LccConverterStationCreationInfos.ShuntCompensatorInfos shuntCompensatorInfos) { + voltageLevel.newShuntCompensator() + .setId(shuntCompensatorInfos.getId()) + .setName(shuntCompensatorInfos.getName()) + .setSectionCount(1) + .setBus(bus.getId()) + .setConnectableBus(bus.getId()) + .newLinearModel() + .setBPerSection((shuntCompensatorInfos.getMaxQAtNominalV()) / Math.pow(voltageLevel.getNominalV(), 2)) + .setMaximumSectionCount(1) + .add() + .add(); + } + + public void shuntCompensatorConnectedToHvdc(Boolean connectedToHvdc, Injection injection, ReportNode subReportNode) { + if (Boolean.TRUE.equals(connectedToHvdc)) { + injection.getTerminal().connect(); + subReportNode.newReportNode() + .withMessageTemplate(EQUIPMENT_CONNECTED_TO_HVDC, "Equipment with id=${id} is connected to Hvdc") + .withUntypedValue("id", injection.getId()) + .withSeverity(TypedValue.INFO_SEVERITY) + .add(); + } else { + injection.getTerminal().disconnect(); + subReportNode.newReportNode() + .withMessageTemplate(EQUIPMENT_NOT_CONNECTED_TO_HVDC, "Equipment with id=${id} is not connected to Hvdc") + .withUntypedValue("id", injection.getId()) + .withSeverity(TypedValue.INFO_SEVERITY) + .add(); + } + } + + private void createShuntCompensatorOnSideInNodeBreaker(VoltageLevel voltageLevel, Network network, + LccConverterStationCreationInfos lccConverterStationCreationInfos, + InjectionAdder injectionAdder, + LccConverterStationCreationInfos.ShuntCompensatorInfos shuntCompensatorOnSide, + ReportNode subReportNode) { + int position = ModificationUtils.getInstance().getPosition(lccConverterStationCreationInfos.getBusOrBusbarSectionId(), network, voltageLevel); + CreateFeederBay algo = new CreateFeederBayBuilder() + .withBusOrBusbarSectionId(lccConverterStationCreationInfos.getBusOrBusbarSectionId()) + .withInjectionDirection(lccConverterStationCreationInfos.getConnectionDirection()) + .withInjectionFeederName(StringUtils.isBlank(shuntCompensatorOnSide.getName()) + ? shuntCompensatorOnSide.getId() + : shuntCompensatorOnSide.getName()) + .withInjectionPositionOrder(position) + .withInjectionAdder(injectionAdder) + .build(); + algo.apply(network, true, subReportNode); + } + + private LccConverterStation createConverterStationInNodeBreaker(Network network, + VoltageLevel voltageLevel, + LccConverterStationCreationInfos lccConverterStationCreationInfos, + ReportNode subReportNode) { + LccConverterStationAdder converterStationAdder = voltageLevel.newLccConverterStation() + .setId(lccConverterStationCreationInfos.getEquipmentId()) + .setName(lccConverterStationCreationInfos.getEquipmentName()); + if (lccConverterStationCreationInfos.getLossFactor() != null) { + converterStationAdder.setLossFactor(lccConverterStationCreationInfos.getLossFactor()); + } + if (lccConverterStationCreationInfos.getPowerFactor() != null) { + converterStationAdder.setPowerFactor(lccConverterStationCreationInfos.getPowerFactor()); + } + createInjectionInNodeBreaker(voltageLevel, lccConverterStationCreationInfos, network, converterStationAdder, subReportNode); + Optional.ofNullable(lccConverterStationCreationInfos.getShuntCompensatorsOnSide()) + .ifPresent(shuntCompensators -> + shuntCompensators.forEach(shuntCompensatorOnSide -> { + ShuntCompensatorAdder shuntCompensatorAdder = createShuntCompensatorInNodeBreaker(voltageLevel, shuntCompensatorOnSide); + createShuntCompensatorOnSideInNodeBreaker(voltageLevel, network, lccConverterStationCreationInfos, + shuntCompensatorAdder, shuntCompensatorOnSide, subReportNode); + shuntCompensatorConnectedToHvdc(shuntCompensatorOnSide.getConnectedToHvdc(), + network.getShuntCompensator(shuntCompensatorOnSide.getId()), subReportNode); + })); + return ModificationUtils.getInstance().getLccConverterStation(network, + lccConverterStationCreationInfos.getEquipmentId()); + } + + private LccConverterStation createConverterStationInBusBreaker(Network network, VoltageLevel voltageLevel, + LccConverterStationCreationInfos lccConverterStationCreationInfos, + ReportNode subReportNode) { + Bus bus = ModificationUtils.getInstance().getBusBreakerBus(voltageLevel, lccConverterStationCreationInfos.getBusOrBusbarSectionId()); + LccConverterStation lccConverterStation = voltageLevel.newLccConverterStation() + .setId(lccConverterStationCreationInfos.getEquipmentId()) + .setName(lccConverterStationCreationInfos.getEquipmentName()) + .setBus(bus.getId()) + .setLossFactor(lccConverterStationCreationInfos.getLossFactor()) + .setPowerFactor(lccConverterStationCreationInfos.getPowerFactor()) + .add(); + + Optional.ofNullable(lccConverterStationCreationInfos.getShuntCompensatorsOnSide()) + .ifPresent(shuntCompensators -> shuntCompensators.forEach(shuntCompensatorOnSide -> { + createShuntCompensatorInBusBreaker(voltageLevel, bus, shuntCompensatorOnSide); + shuntCompensatorConnectedToHvdc( + shuntCompensatorOnSide.getConnectedToHvdc(), + network.getShuntCompensator(shuntCompensatorOnSide.getId()), + subReportNode); + })); + return lccConverterStation; + } + + private void reportHvdcLineInfos(HvdcLine hvdcLine, ReportNode subReportNode) { + if (modificationInfos.getEquipmentName() != null) { + ModificationUtils.getInstance() + .reportElementaryCreation(subReportNode, modificationInfos.getEquipmentName(), "Name"); + } + List characteristicsReport = new ArrayList<>(); + characteristicsReport.add(ModificationUtils.getInstance().buildCreationReport(modificationInfos.getNominalV(), "DC nominal voltage")); + characteristicsReport.add(ModificationUtils.getInstance().buildCreationReport(modificationInfos.getR(), "DC resistance")); + characteristicsReport.add(ModificationUtils.getInstance().buildCreationReport(modificationInfos.getMaxP(), "Pmax")); + ModificationUtils.getInstance().reportModifications(subReportNode, characteristicsReport, LCC_CHARACTERISTICS, CHARACTERISTICS); + List setPointsReports = new ArrayList<>(); + setPointsReports.add(ModificationUtils.getInstance().buildCreationReport(modificationInfos.getConvertersMode(), "Converters mode")); + setPointsReports.add(ModificationUtils.getInstance().buildCreationReport(modificationInfos.getActivePowerSetpoint(), "Active power")); + ModificationUtils.getInstance().reportModifications(subReportNode, setPointsReports, LCC_SETPOINTS, SETPOINTS); + PropertiesUtils.applyProperties(hvdcLine, subReportNode, modificationInfos.getProperties(), "LCC_Properties"); + } + + private void addReportConverterStationLcc(LccConverterStationCreationInfos lccConverterStationCreationInfos, + String logFieldName, ReportNode subReporter) { + ReportNode reportConverterStationNode = subReporter.newReportNode() + .withMessageTemplate("converterStationCreated", "${fieldName} with id=${id} created") + .withUntypedValue("fieldName", logFieldName) + .withUntypedValue("id", lccConverterStationCreationInfos.getEquipmentId()).add(); + + List characteristicsReport = List.of(ModificationUtils.getInstance().buildCreationReport(lccConverterStationCreationInfos.getLossFactor(), "Loss Factor"), + ModificationUtils.getInstance().buildCreationReport(lccConverterStationCreationInfos.getPowerFactor(), "Power Factor")); + List shuntCompensatorsOnSide = Optional.ofNullable(lccConverterStationCreationInfos.getShuntCompensatorsOnSide()) + .orElse(List.of()) + .stream() + .flatMap(shuntCompensatorOnSide -> Stream.of( + ModificationUtils.getInstance().buildCreationReport(shuntCompensatorOnSide.getId(), "Shunt Compensator ID"), + ModificationUtils.getInstance().buildCreationReport(shuntCompensatorOnSide.getName(), "Shunt Compensator Name"), + ModificationUtils.getInstance().buildCreationReport(shuntCompensatorOnSide.getMaxQAtNominalV(), "Q max at nominal voltage"), + ModificationUtils.getInstance().buildCreationReport(shuntCompensatorOnSide.getConnectedToHvdc(), "Connected To Hvdc") + )) + .toList(); + + ModificationUtils.getInstance().reportModifications(reportConverterStationNode, characteristicsReport, "converterStationCharacteristics", CHARACTERISTICS); + reportInjectionCreationConnectivity(lccConverterStationCreationInfos, reportConverterStationNode); + ModificationUtils.getInstance().reportModifications(reportConverterStationNode, shuntCompensatorsOnSide, "converterStationFilters", FILTERS); + + } +} diff --git a/src/main/java/org/gridsuite/modification/utils/ModificationUtils.java b/src/main/java/org/gridsuite/modification/utils/ModificationUtils.java index e7737cd..7614c0e 100644 --- a/src/main/java/org/gridsuite/modification/utils/ModificationUtils.java +++ b/src/main/java/org/gridsuite/modification/utils/ModificationUtils.java @@ -122,6 +122,14 @@ public VscConverterStation getVscConverterStation(Network network, String conver return vscConverterStation; } + public LccConverterStation getLccConverterStation(Network network, String converterStationId) { + LccConverterStation lccConverterStation = network.getLccConverterStation(converterStationId); + if (lccConverterStation == null) { + throw new NetworkModificationException(LCC_CONVERTER_STATION_NOT_FOUND, "Lcc converter station " + converterStationId + NOT_EXIST_IN_NETWORK); + } + return lccConverterStation; + } + //get hvdcline public HvdcLine getHvdcLine(Network network, String hvdcLineId) { HvdcLine hvdcLine = network.getHvdcLine(hvdcLineId); diff --git a/src/test/java/org/gridsuite/modification/modifications/LccCreationInBusBreakerTest.java b/src/test/java/org/gridsuite/modification/modifications/LccCreationInBusBreakerTest.java new file mode 100644 index 0000000..f879117 --- /dev/null +++ b/src/test/java/org/gridsuite/modification/modifications/LccCreationInBusBreakerTest.java @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.modification.modifications; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.powsybl.iidm.network.HvdcLine; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.extensions.ConnectablePosition; +import org.gridsuite.modification.NetworkModificationException; +import org.gridsuite.modification.dto.FreePropertyInfos; +import org.gridsuite.modification.dto.LccConverterStationCreationInfos; +import org.gridsuite.modification.dto.LccCreationInfos; +import org.gridsuite.modification.dto.ModificationInfos; +import org.gridsuite.modification.utils.NetworkCreation; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static org.gridsuite.modification.NetworkModificationException.Type.BUS_NOT_FOUND; +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Ghazwa REHILI + */ +class LccCreationInBusBreakerTest extends AbstractNetworkModificationTest { + + private static final String PROPERTY_NAME = "property-name"; + private static final String PROPERTY_VALUE = "property-value"; + + @Override + protected Network createNetwork(UUID networkUuid) { + return NetworkCreation.createBusBreaker(networkUuid); + } + + @Override + protected ModificationInfos buildModification() { + return LccCreationInfos.builder() + .stashed(false) + .equipmentId("lcc1") + .equipmentName("lcc1Name") + .nominalV(39.) + .r(4.) + .maxP(56.) + .convertersMode(HvdcLine.ConvertersMode.SIDE_1_INVERTER_SIDE_2_RECTIFIER) + .activePowerSetpoint(5.) + .converterStation1(buildConverterStation1WithShuntCompensatorsOnSide()) + .converterStation2(buildConverterStation2WithShuntCompensatorsOnSide()) + .properties(List.of(FreePropertyInfos.builder().name(PROPERTY_NAME).value(PROPERTY_VALUE).build())) + .build(); + } + + private static LccConverterStationCreationInfos buildConverterStation1WithShuntCompensatorsOnSide() { + var filter1 = LccConverterStationCreationInfos.ShuntCompensatorInfos.builder() + .id("ShuntStation1Id1") + .name("ShuntStation1Name1") + .maxQAtNominalV(0.1) + .connectedToHvdc(true) + .build(); + + var filter2 = LccConverterStationCreationInfos.ShuntCompensatorInfos.builder() + .id("ShuntStation1Id2") + .name("ShuntStation1Name2") + .maxQAtNominalV(0.1) + .connectedToHvdc(false) + .build(); + + return LccConverterStationCreationInfos.builder() + .equipmentId("lcc1Station1Id") + .equipmentName("lcc1Station1Name") + .lossFactor(40F) + .powerFactor(1F) + .voltageLevelId("v1") + .busOrBusbarSectionId("bus1") + .connectionName("top") + .connectionDirection(ConnectablePosition.Direction.TOP) + .shuntCompensatorsOnSide(List.of(filter1, filter2)) + .build(); + } + + private static LccConverterStationCreationInfos buildConverterStation2WithShuntCompensatorsOnSide() { + return LccConverterStationCreationInfos.builder() + .equipmentId("lcc2Station2Id") + .equipmentName("lcc2Station2Name") + .lossFactor(40F) + .powerFactor(1F) + .voltageLevelId("v2") + .busOrBusbarSectionId("bus2") + .connectionName("top") + .connectionDirection(ConnectablePosition.Direction.TOP) + .shuntCompensatorsOnSide(List.of()) + .build(); + } + + @Override + protected void assertAfterNetworkModificationApplication() { + assertNotNull(getNetwork().getHvdcLine("lcc1")); + assertEquals(PROPERTY_VALUE, getNetwork().getHvdcLine("lcc1").getProperty(PROPERTY_NAME)); + + } + + @Override + protected void testCreationModificationMessage(ModificationInfos modificationInfos) throws Exception { + assertEquals("LCC_CREATION", modificationInfos.getMessageType()); + Map createdValues = mapper.readValue(modificationInfos.getMessageValues(), new TypeReference<>() { }); + assertEquals("lcc1", createdValues.get("equipmentId")); + } + + @Override + protected void checkModification() { + LccCreationInfos lccCreationInfos = (LccCreationInfos) buildModification(); + lccCreationInfos.getConverterStation1().setBusOrBusbarSectionId("notFoundBus"); + LccCreation lccCreation = (LccCreation) lccCreationInfos.toModification(); + Network network = getNetwork(); + NetworkModificationException exception = assertThrows(NetworkModificationException.class, () -> lccCreation.check(network)); + assertEquals(BUS_NOT_FOUND, exception.getType()); + assertEquals("BUS_NOT_FOUND : notFoundBus", exception.getMessage()); + } +} diff --git a/src/test/java/org/gridsuite/modification/modifications/LccCreationInNodeBreakerTest.java b/src/test/java/org/gridsuite/modification/modifications/LccCreationInNodeBreakerTest.java new file mode 100644 index 0000000..b6261c0 --- /dev/null +++ b/src/test/java/org/gridsuite/modification/modifications/LccCreationInNodeBreakerTest.java @@ -0,0 +1,146 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.modification.modifications; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.powsybl.iidm.network.HvdcLine; +import com.powsybl.iidm.network.LccConverterStation; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.extensions.ConnectablePosition; +import org.gridsuite.modification.NetworkModificationException; +import org.gridsuite.modification.dto.FreePropertyInfos; +import org.gridsuite.modification.dto.LccConverterStationCreationInfos; +import org.gridsuite.modification.dto.LccCreationInfos; +import org.gridsuite.modification.dto.ModificationInfos; +import org.gridsuite.modification.utils.NetworkCreation; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static org.gridsuite.modification.NetworkModificationException.Type.VOLTAGE_LEVEL_NOT_FOUND; +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Ghazwa Rehili + */ +class LccCreationInNodeBreakerTest extends AbstractNetworkModificationTest { + private static final String PROPERTY_NAME = "property-name"; + private static final String PROPERTY_VALUE = "property-value"; + + @Override + protected Network createNetwork(UUID networkUuid) { + return NetworkCreation.create(networkUuid, true); + } + + @Override + protected ModificationInfos buildModification() { + return LccCreationInfos.builder() + .stashed(false) + .equipmentId("lcc1") + .equipmentName("lcc1Name") + .nominalV(39.) + .r(4.) + .maxP(56.) + .convertersMode(HvdcLine.ConvertersMode.SIDE_1_INVERTER_SIDE_2_RECTIFIER) + .activePowerSetpoint(5.) + .converterStation1(buildConverterStation1WithShuntCompensatorsOnSide()) + .converterStation2(buildConverterStation2WithShuntCompensatorsOnSide()) + .properties(List.of(FreePropertyInfos.builder().name(PROPERTY_NAME).value(PROPERTY_VALUE).build())) + .build(); + } + + @Override + protected void assertAfterNetworkModificationApplication() { + assertNotNull(getNetwork().getHvdcLine("lcc1")); + assertEquals(1, getNetwork().getVoltageLevel("v1").getLccConverterStationStream() + .filter(converterStation -> converterStation.getId().equals("lcc1Station1Id")).count()); + assertEquals(1, getNetwork().getVoltageLevel("v2").getLccConverterStationStream() + .filter(converterStation -> converterStation.getId().equals("lcc2Station2Id")).count()); + HvdcLine hvdcLine = getNetwork().getHvdcLine("lcc1"); + assertEquals(HvdcLine.ConvertersMode.SIDE_1_INVERTER_SIDE_2_RECTIFIER, hvdcLine.getConvertersMode()); + assertEquals(39, hvdcLine.getNominalV(), 0); + assertEquals(4, hvdcLine.getR(), 0); + assertEquals(5, hvdcLine.getActivePowerSetpoint(), 0); + assertEquals(56, hvdcLine.getMaxP(), 0); + assertEquals(PROPERTY_VALUE, hvdcLine.getProperty(PROPERTY_NAME)); + LccConverterStation lccConverterStation1 = (LccConverterStation) hvdcLine.getConverterStation1(); + assertNotNull(lccConverterStation1); + assertEquals(40, lccConverterStation1.getLossFactor(), 0); + assertEquals(1, lccConverterStation1.getPowerFactor(), 0); + assertEquals("v1", lccConverterStation1.getTerminal().getVoltageLevel().getId()); + LccConverterStation lccConverterStation2 = (LccConverterStation) hvdcLine.getConverterStation2(); + assertNotNull(lccConverterStation2); + assertEquals(40, lccConverterStation2.getLossFactor(), 0); + assertEquals(1, lccConverterStation2.getPowerFactor(), 0); + assertEquals("v2", lccConverterStation2.getTerminal().getVoltageLevel().getId()); + } + + private static LccConverterStationCreationInfos buildConverterStation1WithShuntCompensatorsOnSide() { + var filter1 = LccConverterStationCreationInfos.ShuntCompensatorInfos.builder() + .id("ShuntStation1Id1") + .name("ShuntStation1Name1") + .maxQAtNominalV(0.1) + .connectedToHvdc(true) + .build(); + + var filter2 = LccConverterStationCreationInfos.ShuntCompensatorInfos.builder() + .id("ShuntStation1Id2") + .name("ShuntStation1Name2") + .maxQAtNominalV(0.1) + .connectedToHvdc(false) + .build(); + + return LccConverterStationCreationInfos.builder() + .equipmentId("lcc1Station1Id") + .equipmentName("lcc1Station1Name") + .lossFactor(40F) + .powerFactor(1F) + .voltageLevelId("v1") + .busOrBusbarSectionId("1.1") + .connectionName("top") + .connectionDirection(ConnectablePosition.Direction.TOP) + .shuntCompensatorsOnSide(List.of(filter1, filter2)) + .build(); + } + + private static LccConverterStationCreationInfos buildConverterStation2WithShuntCompensatorsOnSide() { + return LccConverterStationCreationInfos.builder() + .equipmentId("lcc2Station2Id") + .equipmentName("lcc2Station2Name") + .lossFactor(40F) + .powerFactor(1F) + .voltageLevelId("v2") + .busOrBusbarSectionId("1.1") + .connectionName("top") + .connectionDirection(ConnectablePosition.Direction.TOP) + .shuntCompensatorsOnSide(List.of()) + .build(); + } + + @Override + protected void testCreationModificationMessage(ModificationInfos modificationInfos) throws Exception { + assertEquals("LCC_CREATION", modificationInfos.getMessageType()); + Map createdValues = mapper.readValue(modificationInfos.getMessageValues(), new TypeReference<>() { }); + assertEquals("lcc1", createdValues.get("equipmentId")); + } + + @Override + protected void checkModification() { + LccCreationInfos lccCreationInfos = (LccCreationInfos) buildModification(); + // not found voltage level + lccCreationInfos.setEquipmentId("lccId"); + LccConverterStationCreationInfos converterStationCreationInfos = buildConverterStation1WithShuntCompensatorsOnSide(); + converterStationCreationInfos.setVoltageLevelId("notFoundVoltageLevelId"); + lccCreationInfos.setConverterStation2(converterStationCreationInfos); + LccCreation lccCreation = (LccCreation) lccCreationInfos.toModification(); + Network network = getNetwork(); + NetworkModificationException exception = assertThrows(NetworkModificationException.class, () -> lccCreation.check(network)); + assertEquals(new NetworkModificationException(VOLTAGE_LEVEL_NOT_FOUND, "notFoundVoltageLevelId").getMessage(), exception.getMessage()); + } + +}