Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
@@ -0,0 +1,15 @@
/**
* 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.network.map.dto.definition.voltagelevel;

import com.powsybl.iidm.network.TwoSides;
import org.gridsuite.network.map.dto.definition.extension.ConnectablePositionInfos;

/**
* @author Etienne Lesot <etienne.lesot at rte-france.com>
*/
public record FeederBayInfos(String busbarSectionId, ConnectablePositionInfos connectablePositionInfos, TwoSides connectionSide) { }
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,7 @@ public class VoltageLevelFormInfos extends ElementInfosWithProperties {

@JsonInclude(JsonInclude.Include.NON_NULL)
private Map<String, List<String>> busBarSectionInfos;

@JsonInclude(JsonInclude.Include.NON_NULL)
private Map<String, List<FeederBayInfos>> feederBaysInfos;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.gridsuite.network.map.dto.ElementInfos;
import org.gridsuite.network.map.dto.InfoTypeParameters;
import org.gridsuite.network.map.dto.definition.busbarsection.BusBarSectionFormInfos;
import org.gridsuite.network.map.dto.definition.voltagelevel.FeederBayInfos;
import org.gridsuite.network.map.dto.definition.voltagelevel.VoltageLevelFormInfos;
import org.gridsuite.network.map.dto.definition.voltagelevel.VoltageLevelMapInfos;
import org.gridsuite.network.map.dto.definition.voltagelevel.VoltageLevelTabInfos;
Expand All @@ -23,6 +24,7 @@
import java.util.*;
import java.util.stream.Collectors;

import static com.powsybl.iidm.network.Terminal.getConnectableSide;
import static org.gridsuite.network.map.dto.utils.ElementUtils.*;

/**
Expand Down Expand Up @@ -106,13 +108,36 @@ static VoltageLevelFormInfos toFormInfos(Identifiable<?> identifiable) {
builder.isRetrievedBusbarSections(vlTopologyInfos.isRetrievedBusbarSections());
builder.isBusbarSectionPositionFound(vlTopologyInfos.isBusbarSectionPositionFound());
builder.busBarSectionInfos(vlTopologyInfos.getBusBarSectionInfosGrouped());
builder.feederBaysInfos(getFeederBaysInfos(voltageLevel));
}

builder.identifiableShortCircuit(ExtensionUtils.toIdentifiableShortCircuit(voltageLevel));

return builder.build();
}

private static Map<String, List<FeederBayInfos>> getFeederBaysInfos(VoltageLevel voltageLevel) {
Map<String, List<FeederBayInfos>> feederBayInfos = new HashMap<>();
String currentVoltageLevelId = voltageLevel.getId();
voltageLevel.getConnectableStream()
.filter(connectable -> !(connectable instanceof BusbarSection))
.forEach(connectable -> {
List<FeederBayInfos> connections = new ArrayList<>();
for (Object obj : connectable.getTerminals()) {
Terminal terminal = (Terminal) obj;
if (terminal.getVoltageLevel().getId().equals(currentVoltageLevelId)) {
connections.add(new FeederBayInfos(
getBusOrBusbarSection(terminal),
getConnectablePosition(connectable, FeederSide.from(getConnectableSide(terminal))),
getConnectableSide(terminal).map(ThreeSides::toTwoSides).orElse(null)
));
}
}
feederBayInfos.put(connectable.getId(), connections);
});
return feederBayInfos;
}

static VoltageLevelMapInfos toMapInfos(Identifiable<?> identifiable) {
VoltageLevel voltageLevel = (VoltageLevel) identifiable;
return VoltageLevelMapInfos.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
package org.gridsuite.network.map.dto.utils;

import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.ConnectablePosition;
import com.powsybl.math.graph.TraversalType;
import org.gridsuite.network.map.dto.common.ReactiveCapabilityCurveMapData;
import org.gridsuite.network.map.dto.common.TapChangerData;
import org.gridsuite.network.map.dto.common.TapChangerStepData;
import org.gridsuite.network.map.dto.definition.extension.BusbarSectionFinderTraverser;
import org.gridsuite.network.map.dto.definition.extension.ConnectablePositionInfos;
import org.springframework.lang.NonNull;

import java.util.Collection;
Expand Down Expand Up @@ -39,6 +41,49 @@ public static void setIfNotNan(@NonNull final DoubleConsumer setter, final doubl
}
}

public enum FeederSide {
INJECTION_SINGLE_SIDE,
BRANCH_SIDE_ONE,
BRANCH_SIDE_TWO;

public static FeederSide from(Optional<ThreeSides> connectableSide) {
return connectableSide.map(threeSides -> threeSides == ThreeSides.ONE ? BRANCH_SIDE_ONE : BRANCH_SIDE_TWO).orElse(INJECTION_SINGLE_SIDE);
}
}

private static ConnectablePosition.Feeder getFeederInfos(Identifiable<?> identifiable, FeederSide side) {
ConnectablePosition<?> connectablePosition = (ConnectablePosition<?>) identifiable.getExtension(ConnectablePosition.class);
if (connectablePosition == null) {
return null;
}

switch (side) {
case INJECTION_SINGLE_SIDE:
return connectablePosition.getFeeder();
case BRANCH_SIDE_ONE:
return connectablePosition.getFeeder1();
case BRANCH_SIDE_TWO:
return connectablePosition.getFeeder2();
default:
throw new IllegalArgumentException("Invalid feeder side: " + side);
}
}

public static ConnectablePositionInfos getConnectablePosition(Identifiable<?> identifiable, FeederSide side) {
ConnectablePosition.Feeder feeder = getFeederInfos(identifiable, side);
return buildConnectablePositionInfos(feeder);
}

public static ConnectablePositionInfos buildConnectablePositionInfos(ConnectablePosition.Feeder feeder) {
ConnectablePositionInfos.ConnectablePositionInfosBuilder builder = ConnectablePositionInfos.builder();
if (feeder != null) {
builder.connectionDirection(feeder.getDirection() == null ? null : feeder.getDirection())
.connectionPosition(feeder.getOrder().orElse(null))
.connectionName(feeder.getName().orElse(null));
}
return builder.build();
}

public static String getBusOrBusbarSection(Terminal terminal) {
if (terminal.getVoltageLevel().getTopologyKind().equals(TopologyKind.BUS_BREAKER)) {
if (terminal.isConnected()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,47 @@ void setUp() {
.withDirection(ConnectablePosition.Direction.TOP).add()
.add();

VoltageLevel vlgen7 = p5.newVoltageLevel()
.setId("VLGEN7")
.setNominalV(24.0)
.setHighVoltageLimit(30)
.setLowVoltageLimit(20)
.setTopologyKind(TopologyKind.NODE_BREAKER)
.add();
vlgen7.getNodeBreakerView().newBusbarSection()
.setId("NGEN7")
.setName("NGEN7")
.setNode(0)
.add();
createSwitch(vlgen4, "b4", SwitchKind.DISCONNECTOR, false, 0, 10);
createSwitch(vlgen4, "br11", SwitchKind.BREAKER, false, 10, 11);
createSwitch(vlgen7, "b5", SwitchKind.DISCONNECTOR, false, 0, 1);
createSwitch(vlgen7, "br21", SwitchKind.BREAKER, false, 1, 2);
network.newLine()
.setId("LINE7")
.setVoltageLevel1("VLGEN4")
.setNode1(11)
.setVoltageLevel2("VLGEN7")
.setNode2(2)
.setR(3.0)
.setX(33.0)
.setG1(0.0)
.setB1(386E-6 / 2)
.setG2(0.0)
.setB2(386E-6 / 2)
.add();
Line line7 = network.getLine("LINE7");
line7.newExtension(ConnectablePositionAdder.class)
.newFeeder1()
.withName("LINE7_Side_VLGEN4")
.withOrder(5)
.withDirection(ConnectablePosition.Direction.BOTTOM).add()
.newFeeder2()
.withName("LINE7_Side_VLGEN8")
.withOrder(3)
.withDirection(ConnectablePosition.Direction.TOP).add()
.add();

// Add new variant
network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, VARIANT_ID);
network.getVariantManager().setWorkingVariant(VARIANT_ID);
Expand Down Expand Up @@ -1725,10 +1766,10 @@ void shouldReturnLinesOperatingStatusData() throws Exception {

@Test
void shouldReturnLinesIds() throws Exception {
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4").toString(), ElementType.LINE, null, null);
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4").toString(), ElementType.LINE, null, List.of(24.0, 380.0));
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4").toString(), ElementType.LINE, null, null);
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4").toString(), ElementType.LINE, null, List.of(24.0, 380.0));
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4", "LINE7").toString(), ElementType.LINE, null, null);
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4", "LINE7").toString(), ElementType.LINE, null, List.of(24.0, 380.0));
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4", "LINE7").toString(), ElementType.LINE, null, null);
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4", "LINE7").toString(), ElementType.LINE, null, List.of(24.0, 380.0));
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3").toString(), ElementType.LINE, List.of("P1"), null);
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3").toString(), ElementType.LINE, List.of("P1"), List.of(24.0, 380.0));
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of().toString(), ElementType.LINE, List.of("P1"), List.of(225.0));
Expand Down Expand Up @@ -2247,12 +2288,12 @@ void shouldReturnVotlageLevelsMapData() throws Exception {

@Test
void shouldReturnVoltageLevelsIds() throws Exception {
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6").toString(), ElementType.VOLTAGE_LEVEL, null, null);
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6").toString(), ElementType.VOLTAGE_LEVEL, null, List.of(24.0, 150.0, 225.0, 380.0));
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6").toString(), ElementType.VOLTAGE_LEVEL, null, null);
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6").toString(), ElementType.VOLTAGE_LEVEL, null, List.of(24.0, 150.0, 225.0, 380.0));
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6").toString(), ElementType.VOLTAGE_LEVEL, List.of("P1", "P2", "P3", "P4", "P5", "P6"), null);
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6").toString(), ElementType.VOLTAGE_LEVEL, List.of("P1", "P2", "P3", "P4", "P5", "P6"), List.of(24.0, 150.0, 225.0, 380.0));
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6", "VLGEN7").toString(), ElementType.VOLTAGE_LEVEL, null, null);
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6", "VLGEN7").toString(), ElementType.VOLTAGE_LEVEL, null, List.of(24.0, 150.0, 225.0, 380.0));
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6", "VLGEN7").toString(), ElementType.VOLTAGE_LEVEL, null, null);
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6", "VLGEN7").toString(), ElementType.VOLTAGE_LEVEL, null, List.of(24.0, 150.0, 225.0, 380.0));
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6", "VLGEN7").toString(), ElementType.VOLTAGE_LEVEL, List.of("P1", "P2", "P3", "P4", "P5", "P6"), null);
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6", "VLGEN7").toString(), ElementType.VOLTAGE_LEVEL, List.of("P1", "P2", "P3", "P4", "P5", "P6"), List.of(24.0, 150.0, 225.0, 380.0));
}

@Test
Expand All @@ -2270,11 +2311,16 @@ void shouldReturnNotFoundInsteadOfVoltageLevelsMapData() throws Exception {
}

@Test
void shouldReturnVotlageLevelFormData() throws Exception {
void shouldReturnVoltageLevelFormData() throws Exception {
succeedingTestForElementInfosWithElementId(NETWORK_UUID, null, ElementType.VOLTAGE_LEVEL, InfoType.FORM, "VLGEN4", resourceToString("/voltage-level-form-data.json"));
succeedingTestForElementInfosWithElementId(NETWORK_UUID, VARIANT_ID, ElementType.VOLTAGE_LEVEL, InfoType.FORM, "VLGEN4", resourceToString("/voltage-level-form-data.json"));
}

@Test
void shouldReturnVoltageLevelFormDataWithFeederBaysInfos() throws Exception {
succeedingTestForElementInfosWithElementId(NETWORK_UUID, null, ElementType.VOLTAGE_LEVEL, InfoType.FORM, "VLGEN5", resourceToString("/voltage-level-form-data-feederbays.json"));
}

@Test
void shouldReturnVotlageLevelNonSymmetricalBusbarsFormData() throws Exception {
succeedingTestForElementInfosWithElementId(NETWORK_UUID, null, ElementType.VOLTAGE_LEVEL, InfoType.FORM, "VLGEN5", resourceToString("/voltage-level-non-symmetrical-busbars-form-data.json"));
Expand Down
77 changes: 77 additions & 0 deletions src/test/resources/all-data-in-variant.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@
"ipMin": 0.0,
"ipMax": 100.0
}
},
{
"id": "VLGEN7",
"substationId": "P5",
"nominalV": 24.0,
"country": "FR",
"lowVoltageLimit": 20.0,
"highVoltageLimit": 30.0
}
],
"country": "FR"
Expand Down Expand Up @@ -219,6 +227,14 @@
"ipMin": 0.0,
"ipMax": 100.0
}
},
{
"id": "VLGEN7",
"substationId": "P5",
"nominalV": 24.0,
"country": "FR",
"lowVoltageLimit": 20.0,
"highVoltageLimit": 30.0
}
],
"lines": [
Expand Down Expand Up @@ -588,6 +604,26 @@
"b1": 1.93E-4,
"g2": 0.0,
"b2": 1.93E-4
},
{
"id": "LINE7",
"type": "LINE",
"voltageLevelId1": "VLGEN4",
"voltageLevelId2": "VLGEN7",
"nominalVoltage1": 24.0,
"nominalVoltage2": 24.0,
"substationId1": "P4",
"substationId2": "P5",
"country1": "FR",
"country2": "FR",
"terminal1Connected": true,
"terminal2Connected": true,
"r": 3.0,
"x": 33.0,
"g1": 0.0,
"b1": 1.93E-4,
"g2": 0.0,
"b2": 1.93E-4
}
],
"hvdcLines": [
Expand Down Expand Up @@ -2480,6 +2516,26 @@
"voltageLevelId": "VLGEN6",
"nominalVoltage": 24.0,
"country": "FR"
},
{
"id": "VLGEN4_0",
"v": "NaN",
"angle": "NaN",
"synchronousComponentNum": 1,
"connectedComponentNum": 1,
"voltageLevelId": "VLGEN4",
"nominalVoltage": 24.0,
"country": "FR"
},
{
"id": "VLGEN7_0",
"v": "NaN",
"angle": "NaN",
"synchronousComponentNum": 1,
"connectedComponentNum": 1,
"voltageLevelId": "VLGEN7",
"nominalVoltage": 24.0,
"country": "FR"
}
],
"busbarSections": [
Expand Down Expand Up @@ -2510,6 +2566,11 @@
"id": "NGEN5_2_2",
"name": "NGEN5_2_2",
"voltageLevelId": "VLGEN5"
},
{
"id": "NGEN7",
"name": "NGEN7",
"voltageLevelId": "VLGEN7"
}
],
"branches": [
Expand Down Expand Up @@ -3096,6 +3157,22 @@
"value": 53.0,
"validity": false
}
},
{
"id": "LINE7",
"type": "LINE",
"voltageLevelId1": "VLGEN4",
"voltageLevelId2": "VLGEN7",
"nominalVoltage1": 24.0,
"nominalVoltage2": 24.0,
"substationId1": "P4",
"substationId2": "P5",
"country1": "FR",
"country2": "FR",
"terminal1Connected": true,
"terminal2Connected": true,
"r": 3.0,
"x": 33.0
}
]
}
Loading