Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public enum ModificationType {
CREATE_COUPLING_DEVICE(PreloadingStrategy.NONE),
CREATE_VOLTAGE_LEVEL_TOPOLOGY(PreloadingStrategy.NONE),
LIMIT_SETS_TABULAR_MODIFICATION(PreloadingStrategy.COLLECTION),
CREATE_VOLTAGE_LEVEL_SECTION(PreloadingStrategy.NONE);
CREATE_VOLTAGE_LEVEL_SECTION(PreloadingStrategy.NONE),
MOVE_VOLTAGE_LEVEL_FEEDER_BAYS(PreloadingStrategy.NONE);

private final PreloadingStrategy strategy;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ public enum Type {
MODIFY_VOLTAGE_LEVEL_TOPOLOGY_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
CREATE_COUPLING_DEVICE_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
CREATE_VOLTAGE_LEVEL_TOPOLOGY_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
CREATE_VOLTAGE_LEVEL_SECTION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR);
CREATE_VOLTAGE_LEVEL_SECTION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
MOVE_VOLTAGE_LEVEL_FEEDER_BAYS_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),;

public final HttpStatus status;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Copyright (c) 2025, 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.powsybl.iidm.network.extensions.ConnectablePosition;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;

/**
* @author Etienne Lesot <etienne.lesot at rte-france.com>
*/
@SuperBuilder
@NoArgsConstructor
@Getter
@Setter
@ToString(callSuper = true)
@Schema(description = "Connectable position modification")
public class ConnectablePositionModificationInfos {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public class ConnectablePositionModificationInfos {
public class MoveFeederBayInfos {

@Schema(description = "Connectable id")
private String equipmentId;

@Schema(description = "busbar section id")
private String busbarSectionId;

@Schema(description = "connection side")
private String connectionSide;

@Schema(description = "connection position")
private Integer connectionPosition;

@Schema(description = "connection name")
private String connectionName;

@Schema(description = "connection direction")
private ConnectablePosition.Direction connectionDirection;
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
@JsonSubTypes.Type(value = CreateVoltageLevelTopologyInfos.class),
@JsonSubTypes.Type(value = LimitSetsTabularModificationInfos.class),
@JsonSubTypes.Type(value = CreateVoltageLevelSectionInfos.class),
@JsonSubTypes.Type(value = MoveVoltageLevelFeederBaysInfos.class),
})
@SuperBuilder
@NoArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright (c) 2025, 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 io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.gridsuite.modification.dto.annotation.ModificationErrorTypeName;
import org.gridsuite.modification.modifications.AbstractModification;
import org.gridsuite.modification.modifications.MoveVoltageLevelFeederBays;

import java.util.List;
import java.util.Map;

/**
* @author Etienne Lesot <etienne.lesot at rte-france.com>
*/
@SuperBuilder
@NoArgsConstructor
@Getter
@Setter
@Schema(description = "Move voltage level feeder bays")
@JsonTypeName("MOVE_VOLTAGE_LEVEL_FEEDER_BAYS")
@ModificationErrorTypeName("MOVE_VOLTAGE_LEVEL_FEEDER_BAYS_ERROR")
public class MoveVoltageLevelFeederBaysInfos extends ModificationInfos {

@Schema(description = "Voltage level id")
private String voltageLevelId;

@Schema(description = "Feeder bays list")
private List<ConnectablePositionModificationInfos> feederBaysAttributeList;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private List<ConnectablePositionModificationInfos> feederBaysAttributeList;
private List<ConnectablePositionModificationInfos> feederBays;


@Override
public AbstractModification toModification() {
return new MoveVoltageLevelFeederBays(this);
}

@Override
public ReportNode createSubReportNode(ReportNode reportNode) {
return reportNode.newReportNode()
.withMessageTemplate("network.modification.MOVE_VOLTAGE_LEVEL_FEEDER_BAYS")
.withUntypedValue("voltageLevelId", getVoltageLevelId())
.add();
}

@Override
public Map<String, String> getMapMessageValues() {
return Map.of("voltageLevelId", getVoltageLevelId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/**
* Copyright (c) 2025, 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.iidm.network.*;
import com.powsybl.iidm.network.extensions.ConnectablePosition;
import com.powsybl.iidm.network.extensions.ConnectablePositionAdder;
import org.gridsuite.modification.ModificationType;
import org.gridsuite.modification.NetworkModificationException;
import org.gridsuite.modification.dto.*;
import org.gridsuite.modification.utils.ModificationUtils;

import static org.gridsuite.modification.NetworkModificationException.Type.MOVE_VOLTAGE_LEVEL_FEEDER_BAYS_ERROR;

/**
* @author Etienne Lesot <etienne.lesot at rte-france.com>
*/
public class MoveVoltageLevelFeederBays extends AbstractModification {
private static final String VOLTAGE_LEVEL_NOT_FOUND = "Voltage level %s is not found";
private static final String CONNECTABLE_NOT_FOUND = "Connectable %s not found";
private static final String BUSBAR_NOT_FOUND = "Bus or busbar section %s where connectable %s is supposed to be is not found in voltage level %s";
private static final String UNSUPPORTED_CONNECTABLE = "ConnectablePositionModification is not implemented for %s";
private static final String INVALID_CONNECTION_SIDE = "Invalid connection side: %s for branch %s";

private final MoveVoltageLevelFeederBaysInfos modificationInfos;

public MoveVoltageLevelFeederBays(MoveVoltageLevelFeederBaysInfos modificationInfos) {
this.modificationInfos = modificationInfos;
}

@Override
public void check(Network network) throws NetworkModificationException {
VoltageLevel voltageLevel = checkVoltageLevelOrThrow(network, modificationInfos.getVoltageLevelId());
for (ConnectablePositionModificationInfos info : modificationInfos.getFeederBaysAttributeList()) {
checkBusOrBusbarSection(voltageLevel, info);
checkConnectable(network, info);
}
}

private VoltageLevel checkVoltageLevelOrThrow(Network network, String voltageLevelId) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private VoltageLevel checkVoltageLevelOrThrow(Network network, String voltageLevelId) {
private VoltageLevel getVoltageLevelOrThrow(Network network, String voltageLevelId) {

VoltageLevel voltageLevel = network.getVoltageLevel(voltageLevelId);
if (voltageLevel == null) {
throw new NetworkModificationException(MOVE_VOLTAGE_LEVEL_FEEDER_BAYS_ERROR, String.format(VOLTAGE_LEVEL_NOT_FOUND, voltageLevelId));
}
return voltageLevel;
}

private void checkBusOrBusbarSection(VoltageLevel voltageLevel, ConnectablePositionModificationInfos info) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private void checkBusOrBusbarSection(VoltageLevel voltageLevel, ConnectablePositionModificationInfos info) {
private void checkBusOrBusbarSectionExist(VoltageLevel voltageLevel, ConnectablePositionModificationInfos info) {

boolean busOrBusbarSectionExists = voltageLevel.getTopologyKind().equals(TopologyKind.NODE_BREAKER)
? voltageLevel.getNodeBreakerView().getBusbarSection(info.getBusbarSectionId()) != null
: voltageLevel.getBusBreakerView().getBus(info.getBusbarSectionId()) != null;
if (!busOrBusbarSectionExists) {
throw new NetworkModificationException(MOVE_VOLTAGE_LEVEL_FEEDER_BAYS_ERROR, String.format(BUSBAR_NOT_FOUND,
info.getBusbarSectionId(), info.getEquipmentId(), modificationInfos.getVoltageLevelId()));
}
}

private void checkConnectable(Network network, ConnectablePositionModificationInfos info) {
Connectable<?> connectable = network.getConnectable(info.getEquipmentId());
if (connectable == null) {
throw new NetworkModificationException(MOVE_VOLTAGE_LEVEL_FEEDER_BAYS_ERROR, String.format(CONNECTABLE_NOT_FOUND, info.getEquipmentId()));
}
if (!(connectable instanceof Injection<?>) && !(connectable instanceof Branch<?>)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And it excudes 3WT

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should rather exclude busbarSection as it is done in MoveFeederBay. Something like :
(connectable instanceof BusbarSection) throw ...

throw new NetworkModificationException(MOVE_VOLTAGE_LEVEL_FEEDER_BAYS_ERROR, String.format(UNSUPPORTED_CONNECTABLE, connectable.getClass()));
}
}

@Override
public void apply(Network network, ReportNode subReportNode) {
for (ConnectablePositionModificationInfos info : modificationInfos.getFeederBaysAttributeList()) {
Connectable<?> connectable = network.getConnectable(info.getEquipmentId());
switch (connectable) {
case Injection<?> injection -> modifyInjectionConnectablePosition(network, injection, info, subReportNode);
case Branch<?> branch -> modifyBranchConnectablePosition(network, branch, info, subReportNode);
default -> throw new NetworkModificationException(MOVE_VOLTAGE_LEVEL_FEEDER_BAYS_ERROR, String.format(UNSUPPORTED_CONNECTABLE, connectable.getClass()));
}
}
}

@Override
public String getName() {
return ModificationType.MOVE_VOLTAGE_LEVEL_FEEDER_BAYS.name();
}

private void modifyInjectionConnectablePosition(Network network, Injection<?> injection, ConnectablePositionModificationInfos info, ReportNode subReportNode) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modifyInjectionConnectablePosition and modifyBranchConnectablePosition should be one method modifyConnectablePosition().
With a if else for modifyInjectionConnectivityAttributes() and modifyBranchConnectivityAttributes()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private void modifyInjectionConnectablePosition(Network network, Injection<?> injection, ConnectablePositionModificationInfos info, ReportNode subReportNode) {
private void modifyInjectionConnectablePosition(Network network, Injection<?> injection, ConnectablePositionModificationInfos newConnectablePositionInfos, ReportNode subReportNode) {

ConnectablePosition connectablePosition = injection.getExtension(ConnectablePosition.class);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ConnectablePosition connectablePosition = injection.getExtension(ConnectablePosition.class);
ConnectablePosition oldConnectablePosition = injection.getExtension(ConnectablePosition.class);

ConnectablePositionAdder connectablePositionAdder = injection.newExtension(ConnectablePositionAdder.class);
InjectionModificationInfos injectionModificationInfos = buildInjectionModificationInfos(info);
ModificationUtils.getInstance().modifyInjectionConnectivityAttributes(connectablePosition, connectablePositionAdder, injection, injectionModificationInfos, subReportNode);
moveVoltageLevelBusOrBusbarSection(network, injection, info, subReportNode);
}

private void modifyBranchConnectablePosition(Network network, Branch<?> branch, ConnectablePositionModificationInfos info, ReportNode subReportNode) {
ConnectablePosition connectablePosition = branch.getExtension(ConnectablePosition.class);
ConnectablePositionAdder connectablePositionAdder = branch.newExtension(ConnectablePositionAdder.class);
BranchModificationInfos branchModificationInfos = buildBranchModificationInfos(info);
ModificationUtils.getInstance().modifyBranchConnectivityAttributes(connectablePosition, connectablePositionAdder, branch, branchModificationInfos, subReportNode);
moveVoltageLevelBusOrBusbarSection(network, (Connectable<?>) branch, info, subReportNode);
}

private InjectionModificationInfos buildInjectionModificationInfos(ConnectablePositionModificationInfos info) {
InjectionModificationInfos injectionInfos = new InjectionModificationInfos();
injectionInfos.setEquipmentId(info.getEquipmentId());
injectionInfos.setConnectionPosition(new AttributeModification<>(info.getConnectionPosition(), OperationType.SET));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those 3 rows can be a method. And the method used here and in buildBranchModificationInfos()

injectionInfos.setConnectionName(new AttributeModification<>(info.getConnectionName(), OperationType.SET));
injectionInfos.setConnectionDirection(new AttributeModification<>(info.getConnectionDirection(), OperationType.SET));
return injectionInfos;
}

private BranchModificationInfos buildBranchModificationInfos(ConnectablePositionModificationInfos info) {
BranchModificationInfos branchInfos = new BranchModificationInfos();
branchInfos.setEquipmentId(info.getEquipmentId());

ThreeSides connectionSide = ThreeSides.valueOf(info.getConnectionSide());
switch (connectionSide) {
case ONE -> {
branchInfos.setConnectionPosition1(new AttributeModification<>(info.getConnectionPosition(), OperationType.SET));
branchInfos.setConnectionName1(new AttributeModification<>(info.getConnectionName(), OperationType.SET));
branchInfos.setConnectionDirection1(new AttributeModification<>(info.getConnectionDirection(), OperationType.SET));
}
case TWO -> {
branchInfos.setConnectionPosition2(new AttributeModification<>(info.getConnectionPosition(), OperationType.SET));
branchInfos.setConnectionName2(new AttributeModification<>(info.getConnectionName(), OperationType.SET));
branchInfos.setConnectionDirection2(new AttributeModification<>(info.getConnectionDirection(), OperationType.SET));
}
default -> throw new NetworkModificationException(MOVE_VOLTAGE_LEVEL_FEEDER_BAYS_ERROR, String.format(INVALID_CONNECTION_SIDE, info.getConnectionSide(), branchInfos.getEquipmentId()));
}
return branchInfos;
}

private void moveVoltageLevelBusOrBusbarSection(Network network, Connectable<?> connectable, ConnectablePositionModificationInfos info, ReportNode subReportNode) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should be named moveFeederBay(). And also modifyVoltageLevelBusOrBusBarSectionAttributes() should be named moveFeederBay(). As the only thing they do is apply moveFeederBay() modfication from powsybl-core.

Terminal terminal = getTerminal(network, info);
String currentBusbarId = ModificationUtils.getInstance().getBusOrBusbarSection(terminal);
String targetBusbarId = info.getBusbarSectionId();
if (!currentBusbarId.equals(targetBusbarId)) {
ModificationUtils.getInstance().modifyVoltageLevelBusOrBusBarSectionAttributes(
connectable, terminal,
new AttributeModification<>(modificationInfos.getVoltageLevelId(), OperationType.SET),
new AttributeModification<>(targetBusbarId, OperationType.SET),
subReportNode);
}
}

public Terminal getTerminal(Network network, ConnectablePositionModificationInfos info) {
Connectable<?> connectable = network.getConnectable(info.getEquipmentId());
return switch (connectable) {
case Injection<?> injection -> injection.getTerminal();
case Branch<?> branch -> getTerminalFromBranch(branch, info);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
case Branch<?> branch -> getTerminalFromBranch(branch, info);
case Branch<?> branch -> branch.getTerminal(info.getConnectionSide());

default -> throw new NetworkModificationException(MOVE_VOLTAGE_LEVEL_FEEDER_BAYS_ERROR, String.format(UNSUPPORTED_CONNECTABLE, connectable.getClass()));
};
}

private Terminal getTerminalFromBranch(Branch<?> branch, ConnectablePositionModificationInfos info) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove method

return switch (ThreeSides.valueOf(info.getConnectionSide())) {
case ONE -> branch.getTerminal1();
case TWO -> branch.getTerminal2();
default -> throw new NetworkModificationException(MOVE_VOLTAGE_LEVEL_FEEDER_BAYS_ERROR, String.format(INVALID_CONNECTION_SIDE, info.getConnectionSide(), branch.getId()));
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ public ReportNode modifyBranchConnectivityAttributes(ConnectablePosition<?> conn
return reportModifications(connectivityReports, reports, "network.modification.ConnectivityModified");
}

private void processConnectivityPosition(ConnectablePosition<?> connectablePosition,
public void processConnectivityPosition(ConnectablePosition<?> connectablePosition,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can keep private here :/

ConnectablePositionAdder<?> connectablePositionAdder,
BasicEquipmentModificationInfos modificationInfos,
Network network,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ network.modification.TotalGeneratorUnchangedTargetP = ${nbUnchangedGenerator} el
network.modification.TotalOutwardHvdcFlow = The HVDC balance is : ${hvdcBalance} MW
network.modification.TwoWindingsTransformerProperties = Properties
network.modification.VOLTAGE_LEVEL_TOPOLOGY_MODIFICATION = Voltage Level topology modification ${voltageLevelId}
network.modification.MOVE_VOLTAGE_LEVEL_FEEDER_BAYS = Move voltage level feeder bays modification ${voltageLevelId}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check US specification for logs. That's not what is asked

network.modification.VlProperties = Properties
network.modification.VoltageRegulationCreated = Voltage regulation
network.modification.VoltageRegulationOn = ${status}
Expand Down
Loading