Skip to content

Commit 40b2103

Browse files
authored
get feeder bays infos (#292)
* get feeder bays infos * copy * fix test Signed-off-by: Ghazwa Rehili <[email protected]>
1 parent 2ad53fb commit 40b2103

27 files changed

+643
-13
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Copyright (c) 2025, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
package org.gridsuite.network.map.dto.definition.voltagelevel;
8+
9+
import com.powsybl.iidm.network.TwoSides;
10+
import org.gridsuite.network.map.dto.definition.extension.ConnectablePositionInfos;
11+
12+
/**
13+
* @author Etienne Lesot <etienne.lesot at rte-france.com>
14+
*/
15+
public record FeederBayInfos(String busbarSectionId, ConnectablePositionInfos connectablePositionInfos, TwoSides connectionSide) { }

src/main/java/org/gridsuite/network/map/dto/definition/voltagelevel/VoltageLevelFormInfos.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,7 @@ public class VoltageLevelFormInfos extends ElementInfosWithProperties {
5959

6060
@JsonInclude(JsonInclude.Include.NON_NULL)
6161
private Map<String, List<String>> busBarSectionInfos;
62+
63+
@JsonInclude(JsonInclude.Include.NON_NULL)
64+
private Map<String, List<FeederBayInfos>> feederBaysInfos;
6265
}

src/main/java/org/gridsuite/network/map/dto/mapper/VoltageLevelInfosMapper.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.gridsuite.network.map.dto.ElementInfos;
1515
import org.gridsuite.network.map.dto.InfoTypeParameters;
1616
import org.gridsuite.network.map.dto.definition.busbarsection.BusBarSectionFormInfos;
17+
import org.gridsuite.network.map.dto.definition.voltagelevel.FeederBayInfos;
1718
import org.gridsuite.network.map.dto.definition.voltagelevel.VoltageLevelFormInfos;
1819
import org.gridsuite.network.map.dto.definition.voltagelevel.VoltageLevelMapInfos;
1920
import org.gridsuite.network.map.dto.definition.voltagelevel.VoltageLevelTabInfos;
@@ -23,6 +24,7 @@
2324
import java.util.*;
2425
import java.util.stream.Collectors;
2526

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

2830
/**
@@ -106,13 +108,36 @@ static VoltageLevelFormInfos toFormInfos(Identifiable<?> identifiable) {
106108
builder.isRetrievedBusbarSections(vlTopologyInfos.isRetrievedBusbarSections());
107109
builder.isBusbarSectionPositionFound(vlTopologyInfos.isBusbarSectionPositionFound());
108110
builder.busBarSectionInfos(vlTopologyInfos.getBusBarSectionInfosGrouped());
111+
builder.feederBaysInfos(getFeederBaysInfos(voltageLevel));
109112
}
110113

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

113116
return builder.build();
114117
}
115118

119+
private static Map<String, List<FeederBayInfos>> getFeederBaysInfos(VoltageLevel voltageLevel) {
120+
Map<String, List<FeederBayInfos>> feederBayInfos = new HashMap<>();
121+
String currentVoltageLevelId = voltageLevel.getId();
122+
voltageLevel.getConnectableStream()
123+
.filter(connectable -> !(connectable instanceof BusbarSection))
124+
.forEach(connectable -> {
125+
List<FeederBayInfos> connections = new ArrayList<>();
126+
for (Object obj : connectable.getTerminals()) {
127+
Terminal terminal = (Terminal) obj;
128+
if (terminal.getVoltageLevel().getId().equals(currentVoltageLevelId)) {
129+
connections.add(new FeederBayInfos(
130+
getBusOrBusbarSection(terminal),
131+
getConnectablePosition(connectable, FeederSide.from(getConnectableSide(terminal))),
132+
getConnectableSide(terminal).map(ThreeSides::toTwoSides).orElse(null)
133+
));
134+
}
135+
}
136+
feederBayInfos.put(connectable.getId(), connections);
137+
});
138+
return feederBayInfos;
139+
}
140+
116141
static VoltageLevelMapInfos toMapInfos(Identifiable<?> identifiable) {
117142
VoltageLevel voltageLevel = (VoltageLevel) identifiable;
118143
return VoltageLevelMapInfos.builder()

src/main/java/org/gridsuite/network/map/dto/utils/ElementUtils.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
package org.gridsuite.network.map.dto.utils;
88

99
import com.powsybl.iidm.network.*;
10+
import com.powsybl.iidm.network.extensions.ConnectablePosition;
1011
import com.powsybl.math.graph.TraversalType;
1112
import org.gridsuite.network.map.dto.common.ReactiveCapabilityCurveMapData;
1213
import org.gridsuite.network.map.dto.common.TapChangerData;
1314
import org.gridsuite.network.map.dto.common.TapChangerStepData;
1415
import org.gridsuite.network.map.dto.definition.extension.BusbarSectionFinderTraverser;
16+
import org.gridsuite.network.map.dto.definition.extension.ConnectablePositionInfos;
1517
import org.springframework.lang.NonNull;
1618

1719
import java.util.Collection;
@@ -39,6 +41,49 @@ public static void setIfNotNan(@NonNull final DoubleConsumer setter, final doubl
3941
}
4042
}
4143

44+
public enum FeederSide {
45+
INJECTION_SINGLE_SIDE,
46+
BRANCH_SIDE_ONE,
47+
BRANCH_SIDE_TWO;
48+
49+
public static FeederSide from(Optional<ThreeSides> connectableSide) {
50+
return connectableSide.map(threeSides -> threeSides == ThreeSides.ONE ? BRANCH_SIDE_ONE : BRANCH_SIDE_TWO).orElse(INJECTION_SINGLE_SIDE);
51+
}
52+
}
53+
54+
private static ConnectablePosition.Feeder getFeederInfos(Identifiable<?> identifiable, FeederSide side) {
55+
ConnectablePosition<?> connectablePosition = (ConnectablePosition<?>) identifiable.getExtension(ConnectablePosition.class);
56+
if (connectablePosition == null) {
57+
return null;
58+
}
59+
60+
switch (side) {
61+
case INJECTION_SINGLE_SIDE:
62+
return connectablePosition.getFeeder();
63+
case BRANCH_SIDE_ONE:
64+
return connectablePosition.getFeeder1();
65+
case BRANCH_SIDE_TWO:
66+
return connectablePosition.getFeeder2();
67+
default:
68+
throw new IllegalArgumentException("Invalid feeder side: " + side);
69+
}
70+
}
71+
72+
public static ConnectablePositionInfos getConnectablePosition(Identifiable<?> identifiable, FeederSide side) {
73+
ConnectablePosition.Feeder feeder = getFeederInfos(identifiable, side);
74+
return buildConnectablePositionInfos(feeder);
75+
}
76+
77+
public static ConnectablePositionInfos buildConnectablePositionInfos(ConnectablePosition.Feeder feeder) {
78+
ConnectablePositionInfos.ConnectablePositionInfosBuilder builder = ConnectablePositionInfos.builder();
79+
if (feeder != null) {
80+
builder.connectionDirection(feeder.getDirection() == null ? null : feeder.getDirection())
81+
.connectionPosition(feeder.getOrder().orElse(null))
82+
.connectionName(feeder.getName().orElse(null));
83+
}
84+
return builder.build();
85+
}
86+
4287
public static String getBusOrBusbarSection(Terminal terminal) {
4388
if (terminal.getVoltageLevel().getTopologyKind().equals(TopologyKind.BUS_BREAKER)) {
4489
if (terminal.isConnected()) {

src/test/java/org/gridsuite/network/map/NetworkMapControllerTest.java

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,47 @@ void setUp() {
11581158
.withDirection(ConnectablePosition.Direction.TOP).add()
11591159
.add();
11601160

1161+
VoltageLevel vlgen7 = p5.newVoltageLevel()
1162+
.setId("VLGEN7")
1163+
.setNominalV(24.0)
1164+
.setHighVoltageLimit(30)
1165+
.setLowVoltageLimit(20)
1166+
.setTopologyKind(TopologyKind.NODE_BREAKER)
1167+
.add();
1168+
vlgen7.getNodeBreakerView().newBusbarSection()
1169+
.setId("NGEN7")
1170+
.setName("NGEN7")
1171+
.setNode(0)
1172+
.add();
1173+
createSwitch(vlgen4, "b4", SwitchKind.DISCONNECTOR, false, 0, 10);
1174+
createSwitch(vlgen4, "br11", SwitchKind.BREAKER, false, 10, 11);
1175+
createSwitch(vlgen7, "b5", SwitchKind.DISCONNECTOR, false, 0, 1);
1176+
createSwitch(vlgen7, "br21", SwitchKind.BREAKER, false, 1, 2);
1177+
network.newLine()
1178+
.setId("LINE7")
1179+
.setVoltageLevel1("VLGEN4")
1180+
.setNode1(11)
1181+
.setVoltageLevel2("VLGEN7")
1182+
.setNode2(2)
1183+
.setR(3.0)
1184+
.setX(33.0)
1185+
.setG1(0.0)
1186+
.setB1(386E-6 / 2)
1187+
.setG2(0.0)
1188+
.setB2(386E-6 / 2)
1189+
.add();
1190+
Line line7 = network.getLine("LINE7");
1191+
line7.newExtension(ConnectablePositionAdder.class)
1192+
.newFeeder1()
1193+
.withName("LINE7_Side_VLGEN4")
1194+
.withOrder(5)
1195+
.withDirection(ConnectablePosition.Direction.BOTTOM).add()
1196+
.newFeeder2()
1197+
.withName("LINE7_Side_VLGEN8")
1198+
.withOrder(3)
1199+
.withDirection(ConnectablePosition.Direction.TOP).add()
1200+
.add();
1201+
11611202
// Add new variant
11621203
network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, VARIANT_ID);
11631204
network.getVariantManager().setWorkingVariant(VARIANT_ID);
@@ -1725,10 +1766,10 @@ void shouldReturnLinesOperatingStatusData() throws Exception {
17251766

17261767
@Test
17271768
void shouldReturnLinesIds() throws Exception {
1728-
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4").toString(), ElementType.LINE, null, null);
1729-
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4").toString(), ElementType.LINE, null, List.of(24.0, 380.0));
1730-
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4").toString(), ElementType.LINE, null, null);
1731-
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));
1769+
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4", "LINE7").toString(), ElementType.LINE, null, null);
1770+
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));
1771+
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3", "LINE4", "LINE7").toString(), ElementType.LINE, null, null);
1772+
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));
17321773
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("NHV1_NHV2_1", "NHV1_NHV2_2", "LINE3").toString(), ElementType.LINE, List.of("P1"), null);
17331774
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));
17341775
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of().toString(), ElementType.LINE, List.of("P1"), List.of(225.0));
@@ -2247,12 +2288,12 @@ void shouldReturnVotlageLevelsMapData() throws Exception {
22472288

22482289
@Test
22492290
void shouldReturnVoltageLevelsIds() throws Exception {
2250-
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6").toString(), ElementType.VOLTAGE_LEVEL, null, null);
2251-
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));
2252-
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6").toString(), ElementType.VOLTAGE_LEVEL, null, null);
2253-
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));
2254-
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);
2255-
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));
2291+
succeedingTestForElementsIds(NETWORK_UUID, null, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6", "VLGEN7").toString(), ElementType.VOLTAGE_LEVEL, null, null);
2292+
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));
2293+
succeedingTestForElementsIds(NETWORK_UUID, VARIANT_ID, List.of("VL", "VLGEN", "VLHV1", "VLHV2", "VLLOAD", "VLNEW2", "VLGEN3", "VLGEN4", "VLGEN5", "VLGEN6", "VLGEN7").toString(), ElementType.VOLTAGE_LEVEL, null, null);
2294+
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));
2295+
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);
2296+
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));
22562297
}
22572298

22582299
@Test
@@ -2270,11 +2311,16 @@ void shouldReturnNotFoundInsteadOfVoltageLevelsMapData() throws Exception {
22702311
}
22712312

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

2319+
@Test
2320+
void shouldReturnVoltageLevelFormDataWithFeederBaysInfos() throws Exception {
2321+
succeedingTestForElementInfosWithElementId(NETWORK_UUID, null, ElementType.VOLTAGE_LEVEL, InfoType.FORM, "VLGEN5", resourceToString("/voltage-level-form-data-feederbays.json"));
2322+
}
2323+
22782324
@Test
22792325
void shouldReturnVotlageLevelNonSymmetricalBusbarsFormData() throws Exception {
22802326
succeedingTestForElementInfosWithElementId(NETWORK_UUID, null, ElementType.VOLTAGE_LEVEL, InfoType.FORM, "VLGEN5", resourceToString("/voltage-level-non-symmetrical-busbars-form-data.json"));

src/test/resources/all-data-in-variant.json

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,14 @@
126126
"ipMin": 0.0,
127127
"ipMax": 100.0
128128
}
129+
},
130+
{
131+
"id": "VLGEN7",
132+
"substationId": "P5",
133+
"nominalV": 24.0,
134+
"country": "FR",
135+
"lowVoltageLimit": 20.0,
136+
"highVoltageLimit": 30.0
129137
}
130138
],
131139
"country": "FR"
@@ -219,6 +227,14 @@
219227
"ipMin": 0.0,
220228
"ipMax": 100.0
221229
}
230+
},
231+
{
232+
"id": "VLGEN7",
233+
"substationId": "P5",
234+
"nominalV": 24.0,
235+
"country": "FR",
236+
"lowVoltageLimit": 20.0,
237+
"highVoltageLimit": 30.0
222238
}
223239
],
224240
"lines": [
@@ -588,6 +604,26 @@
588604
"b1": 1.93E-4,
589605
"g2": 0.0,
590606
"b2": 1.93E-4
607+
},
608+
{
609+
"id": "LINE7",
610+
"type": "LINE",
611+
"voltageLevelId1": "VLGEN4",
612+
"voltageLevelId2": "VLGEN7",
613+
"nominalVoltage1": 24.0,
614+
"nominalVoltage2": 24.0,
615+
"substationId1": "P4",
616+
"substationId2": "P5",
617+
"country1": "FR",
618+
"country2": "FR",
619+
"terminal1Connected": true,
620+
"terminal2Connected": true,
621+
"r": 3.0,
622+
"x": 33.0,
623+
"g1": 0.0,
624+
"b1": 1.93E-4,
625+
"g2": 0.0,
626+
"b2": 1.93E-4
591627
}
592628
],
593629
"hvdcLines": [
@@ -2480,6 +2516,26 @@
24802516
"voltageLevelId": "VLGEN6",
24812517
"nominalVoltage": 24.0,
24822518
"country": "FR"
2519+
},
2520+
{
2521+
"id": "VLGEN4_0",
2522+
"v": "NaN",
2523+
"angle": "NaN",
2524+
"synchronousComponentNum": 1,
2525+
"connectedComponentNum": 1,
2526+
"voltageLevelId": "VLGEN4",
2527+
"nominalVoltage": 24.0,
2528+
"country": "FR"
2529+
},
2530+
{
2531+
"id": "VLGEN7_0",
2532+
"v": "NaN",
2533+
"angle": "NaN",
2534+
"synchronousComponentNum": 1,
2535+
"connectedComponentNum": 1,
2536+
"voltageLevelId": "VLGEN7",
2537+
"nominalVoltage": 24.0,
2538+
"country": "FR"
24832539
}
24842540
],
24852541
"busbarSections": [
@@ -2510,6 +2566,11 @@
25102566
"id": "NGEN5_2_2",
25112567
"name": "NGEN5_2_2",
25122568
"voltageLevelId": "VLGEN5"
2569+
},
2570+
{
2571+
"id": "NGEN7",
2572+
"name": "NGEN7",
2573+
"voltageLevelId": "VLGEN7"
25132574
}
25142575
],
25152576
"branches": [
@@ -3096,6 +3157,22 @@
30963157
"value": 53.0,
30973158
"validity": false
30983159
}
3160+
},
3161+
{
3162+
"id": "LINE7",
3163+
"type": "LINE",
3164+
"voltageLevelId1": "VLGEN4",
3165+
"voltageLevelId2": "VLGEN7",
3166+
"nominalVoltage1": 24.0,
3167+
"nominalVoltage2": 24.0,
3168+
"substationId1": "P4",
3169+
"substationId2": "P5",
3170+
"country1": "FR",
3171+
"country2": "FR",
3172+
"terminal1Connected": true,
3173+
"terminal2Connected": true,
3174+
"r": 3.0,
3175+
"x": 33.0
30993176
}
31003177
]
31013178
}

0 commit comments

Comments
 (0)