CreateBranchFeederBaysTest.java
/**
* Copyright (c) 2022, 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.iidm.modification.topology;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.report.PowsyblCoreReportResourceBundle;
import com.powsybl.commons.test.PowsyblCoreTestReportResourceBundle;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.iidm.modification.AbstractNetworkModification;
import com.powsybl.iidm.modification.NetworkModification;
import com.powsybl.iidm.network.Line;
import com.powsybl.iidm.network.LineAdder;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.TwoWindingsTransformerAdder;
import com.powsybl.iidm.network.extensions.ConnectablePosition;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
import org.apache.commons.lang3.Range;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.time.ZonedDateTime;
import java.util.Optional;
import static com.powsybl.iidm.modification.topology.TopologyModificationUtils.getUnusedOrderPositionsAfter;
import static com.powsybl.iidm.modification.topology.TopologyModificationUtils.getUnusedOrderPositionsBefore;
import static com.powsybl.iidm.network.extensions.ConnectablePosition.Direction.BOTTOM;
import static com.powsybl.iidm.network.extensions.ConnectablePosition.Direction.TOP;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author Miora Vedelago {@literal <miora.ralambotiana at rte-france.com>}
*/
class CreateBranchFeederBaysTest extends AbstractModificationTest {
private final Network bbNetwork = EurostagTutorialExample1Factory.create().setCaseDate(ZonedDateTime.parse("2013-01-15T18:45:00.000+01:00"));
private final Network nbNetwork = Network.read("testNetworkNodeBreaker.xiidm", getClass().getResourceAsStream("/testNetworkNodeBreaker.xiidm"));
@Test
void baseNodeBreakerLineTest() throws IOException {
LineAdder lineAdder = nbNetwork.newLine()
.setId("lineTest")
.setR(1.0)
.setX(1.0)
.setG1(0.0)
.setG2(0.0)
.setB1(0.0)
.setB2(0.0);
NetworkModification modification = new CreateBranchFeederBaysBuilder()
.withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("bbs5")
.withPositionOrder1(85)
.withDirection1(BOTTOM)
.withFeederName1("lineTestFeeder1")
.withBusOrBusbarSectionId2("bbs1")
.withPositionOrder2(75)
.withFeederName2("lineTestFeeder2")
.withDirection2(TOP)
.build();
modification.apply(nbNetwork);
writeXmlTest(nbNetwork, "/network-node-breaker-with-new-line.xml");
}
@Test
void baseBusBreakerLineTest() throws IOException {
LineAdder lineAdder = bbNetwork.newLine()
.setId("lineTest")
.setR(1.0)
.setX(1.0)
.setG1(0.0)
.setG2(0.0)
.setB1(0.0)
.setB2(0.0);
NetworkModification modification = new CreateBranchFeederBaysBuilder()
.withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("NGEN")
.withPositionOrder1(85)
.withDirection1(BOTTOM)
.withFeederName1("lineTestFeeder1")
.withBusOrBusbarSectionId2("NHV1")
.withFeederName2("lineTestFeeder2")
.withDirection2(TOP)
.build();
modification.apply(bbNetwork);
writeXmlTest(bbNetwork, "/eurostag-create-line-feeder-bays.xml");
}
@Test
void usedOrderLineTest() throws IOException {
LineAdder lineAdder = nbNetwork.newLine()
.setId("lineTest")
.setR(1.0)
.setX(1.0)
.setG1(0.0)
.setG2(0.0)
.setB1(0.0)
.setB2(0.0);
NetworkModification modification = new CreateBranchFeederBaysBuilder()
.withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("bbs1")
.withPositionOrder1(70)
.withDirection1(TOP)
.withBusOrBusbarSectionId2("bbs5")
.withPositionOrder2(85)
.withDirection2(BOTTOM)
.build();
modification.apply(nbNetwork);
writeXmlTest(nbNetwork, "/network-node-breaker-with-new-line-order-used.xml");
}
@Test
void baseInternalLineTest() throws IOException {
LineAdder lineAdder = nbNetwork.newLine()
.setId("lineTest")
.setR(1.0)
.setX(1.0)
.setG1(0.0)
.setG2(0.0)
.setB1(0.0)
.setB2(0.0);
NetworkModification modification = new CreateBranchFeederBaysBuilder()
.withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("bbs2")
.withPositionOrder1(105)
.withDirection1(TOP)
.withBusOrBusbarSectionId2("bbs1")
.withPositionOrder2(14)
.withDirection2(BOTTOM)
.build();
modification.apply(nbNetwork);
writeXmlTest(nbNetwork, "/network-node-breaker-with-new-internal-line.xml");
}
@Test
void getUnusedOrderPositionAfter() {
LineAdder lineAdder = nbNetwork.newLine()
.setId("lineTest")
.setR(1.0)
.setX(1.0)
.setG1(0.0)
.setG2(0.0)
.setB1(0.0)
.setB2(0.0);
Optional<Range<Integer>> unusedOrderPositionsAfter = getUnusedOrderPositionsAfter(nbNetwork.getBusbarSection("bbs2"));
assertTrue(unusedOrderPositionsAfter.isPresent());
assertEquals(121, (int) unusedOrderPositionsAfter.get().getMinimum());
assertEquals(Integer.MAX_VALUE, (int) unusedOrderPositionsAfter.get().getMaximum());
int positionOrder1 = unusedOrderPositionsAfter.get().getMinimum();
NetworkModification modification = new CreateBranchFeederBaysBuilder()
.withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("bbs2")
.withPositionOrder1(positionOrder1)
.withDirection1(TOP)
.withBusOrBusbarSectionId2("bbs5")
.withPositionOrder2(115)
.withDirection2(BOTTOM)
.build();
modification.apply(nbNetwork);
ConnectablePosition<Line> newLine = nbNetwork.getLine("lineTest").getExtension(ConnectablePosition.class);
assertEquals(TOP, newLine.getFeeder1().getDirection());
assertEquals(Optional.of(121), newLine.getFeeder1().getOrder());
}
@Test
void getUnusedOrderPositionBefore() {
LineAdder lineAdder = nbNetwork.newLine()
.setId("lineTest")
.setR(1.0)
.setX(1.0)
.setG1(0.0)
.setG2(0.0)
.setB1(0.0)
.setB2(0.0);
Optional<Range<Integer>> unusedOrderPositionsBefore = getUnusedOrderPositionsBefore(nbNetwork.getBusbarSection("bbs2"));
assertTrue(unusedOrderPositionsBefore.isPresent());
assertEquals(71, (int) unusedOrderPositionsBefore.get().getMinimum());
assertEquals(79, (int) unusedOrderPositionsBefore.get().getMaximum());
int positionOrder1 = unusedOrderPositionsBefore.get().getMaximum();
NetworkModification modification = new CreateBranchFeederBaysBuilder()
.withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("bbs5")
.withPositionOrder1(115)
.withDirection1(BOTTOM)
.withBusOrBusbarSectionId2("bbs2")
.withPositionOrder2(positionOrder1)
.withDirection2(BOTTOM)
.build();
modification.apply(nbNetwork);
ConnectablePosition<Line> newLine = nbNetwork.getLine("lineTest").getExtension(ConnectablePosition.class);
assertEquals(BOTTOM, newLine.getFeeder2().getDirection());
assertEquals(Optional.of(79), newLine.getFeeder2().getOrder());
}
@Test
void testException() {
LineAdder lineAdder = nbNetwork.newLine()
.setId("lineTest")
.setR(1.0)
.setX(1.0)
.setG1(0.0)
.setG2(0.0)
.setB1(0.0)
.setB2(0.0);
//wrong network
ReportNode reportNode1 = ReportNode.newRootReportNode()
.withResourceBundles(PowsyblCoreTestReportResourceBundle.TEST_BASE_NAME, PowsyblCoreReportResourceBundle.BASE_NAME)
.withMessageTemplate("reportTestWrongNetwork")
.build();
Network network1 = Network.read("testNetworkNodeBreaker.xiidm", getClass().getResourceAsStream("/testNetworkNodeBreaker.xiidm"));
CreateBranchFeederBays modification0 = new CreateBranchFeederBaysBuilder().
withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("bbs1")
.withPositionOrder1(115)
.withDirection1(BOTTOM)
.withBusOrBusbarSectionId2("bbs5")
.withPositionOrder2(115)
.withDirection2(BOTTOM)
.build();
assertDoesNotThrow(() -> modification0.apply(network1, false, ReportNode.NO_OP));
PowsyblException e0 = assertThrows(PowsyblException.class, () -> modification0.apply(network1, true, reportNode1));
assertEquals("Network given in parameters and in connectableAdder are different. Connectable lineTest of type LINE was added then removed", e0.getMessage());
assertEquals("core.iidm.modification.networkMismatch", reportNode1.getChildren().get(0).getMessageKey());
// not found id
ReportNode reportNode2 = ReportNode.newRootReportNode()
.withResourceBundles(PowsyblCoreTestReportResourceBundle.TEST_BASE_NAME, PowsyblCoreReportResourceBundle.BASE_NAME)
.withMessageTemplate("reportTestUndefinedId")
.build();
CreateBranchFeederBays modification1 = new CreateBranchFeederBaysBuilder().
withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("bbs")
.withPositionOrder1(115)
.withDirection1(BOTTOM)
.withBusOrBusbarSectionId2("bbs5")
.withPositionOrder2(115)
.withDirection2(BOTTOM)
.build();
assertDoesNotThrow(() -> modification1.apply(nbNetwork, false, ReportNode.NO_OP));
PowsyblException e1 = assertThrows(PowsyblException.class, () -> modification1.apply(nbNetwork, true, reportNode2));
assertEquals("Bus or busbar section bbs not found", e1.getMessage());
assertEquals("core.iidm.modification.notFoundBusOrBusbarSection", reportNode2.getChildren().get(0).getMessageKey());
// wrong identifiable type
ReportNode reportNode3 = ReportNode.newRootReportNode()
.withResourceBundles(PowsyblCoreTestReportResourceBundle.TEST_BASE_NAME, PowsyblCoreReportResourceBundle.BASE_NAME)
.withMessageTemplate("reportTestWrongBbsType")
.build();
CreateBranchFeederBays modification2 = new CreateBranchFeederBaysBuilder().
withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("gen1")
.withPositionOrder1(115)
.withDirection1(BOTTOM)
.withBusOrBusbarSectionId2("bbs5")
.withPositionOrder2(115)
.withDirection2(BOTTOM)
.build();
assertDoesNotThrow(() -> modification2.apply(nbNetwork, false, ReportNode.NO_OP));
PowsyblException e2 = assertThrows(PowsyblException.class, () -> modification2.apply(nbNetwork, true, reportNode3));
assertEquals("Unsupported type GENERATOR for identifiable gen1", e2.getMessage());
assertEquals("core.iidm.modification.unsupportedIdentifiableType", reportNode3.getChildren().get(0).getMessageKey());
}
@Test
void baseNodeBreakerTwoWindingsTransformerTest() throws IOException {
TwoWindingsTransformerAdder twtAdder = nbNetwork.getSubstation("subst")
.newTwoWindingsTransformer()
.setId("twtTest")
.setR(1.0)
.setX(1.0)
.setG(0.0)
.setB(0.0)
.setRatedU1(220.0)
.setRatedU2(400.0);
NetworkModification modification = new CreateBranchFeederBaysBuilder()
.withBranchAdder(twtAdder)
.withBusOrBusbarSectionId1("bbs5")
.withPositionOrder1(115)
.withDirection1(BOTTOM)
.withBusOrBusbarSectionId2("bbs1")
.withPositionOrder2(71)
.withDirection2(TOP)
.build();
modification.apply(nbNetwork);
writeXmlTest(nbNetwork, "/network-node-breaker-with-new-twt-feeders-bbs.xml");
}
@Test
void baseBusBreakerTwoWindingsTransformerTest() throws IOException {
TwoWindingsTransformerAdder twtAdder = bbNetwork.getSubstation("P1")
.newTwoWindingsTransformer()
.setId("twtTest")
.setR(1.0)
.setX(1.0)
.setG(0.0)
.setB(0.0)
.setRatedU1(220.0)
.setRatedU2(400.0);
NetworkModification modification = new CreateBranchFeederBaysBuilder()
.withBranchAdder(twtAdder)
.withBusOrBusbarSectionId1("NGEN")
.withPositionOrder1(115)
.withDirection1(BOTTOM)
.withBusOrBusbarSectionId2("NHV1")
.withPositionOrder2(121)
.withDirection2(TOP)
.build();
modification.apply(bbNetwork);
writeXmlTest(bbNetwork, "/eurostag-create-twt-feeder-bays.xml");
}
@Test
void testWithoutExtension() {
Network network = Network.read("testNetworkNodeBreakerWithoutExtensions.xiidm", getClass().getResourceAsStream("/testNetworkNodeBreakerWithoutExtensions.xiidm"));
LineAdder lineAdder = network.newLine()
.setId("lineTest")
.setR(1.0)
.setX(1.0)
.setG1(0.0)
.setG2(0.0)
.setB1(0.0)
.setB2(0.0);
new CreateBranchFeederBaysBuilder()
.withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("bbs5")
.withPositionOrder1(115)
.withDirection1(BOTTOM)
.withBusOrBusbarSectionId2("bbs1")
.withPositionOrder2(121)
.withDirection2(TOP)
.build()
.apply(network, true, ReportNode.NO_OP);
Line line = network.getLine("lineTest");
assertNotNull(line);
ConnectablePosition<Line> position = line.getExtension(ConnectablePosition.class);
assertNull(position);
}
@Test
void testWithReportNode() throws IOException {
LineAdder lineAdder = nbNetwork.newLine()
.setId("lineTest")
.setR(1.0)
.setX(1.0)
.setG1(0.0)
.setG2(0.0)
.setB1(0.0)
.setB2(0.0);
ReportNode reportNode = ReportNode.newRootReportNode()
.withResourceBundles(PowsyblCoreTestReportResourceBundle.TEST_BASE_NAME, PowsyblCoreReportResourceBundle.BASE_NAME)
.withMessageTemplate("reportTestCreateLine")
.build();
new CreateBranchFeederBaysBuilder()
.withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("bbs5")
.withPositionOrder1(85)
.withDirection1(BOTTOM)
.withFeederName1("lineTestFeeder1")
.withBusOrBusbarSectionId2("bbs1")
.withPositionOrder2(75)
.withFeederName2("lineTestFeeder2")
.withDirection2(TOP)
.build().apply(nbNetwork, true, reportNode);
testReportNode(reportNode, "/reportNode/create-line-NB-report.txt");
}
@Test
void testReportNodeWithoutExtension() throws IOException {
Network network = Network.read("testNetworkNodeBreakerWithoutExtensions.xiidm", getClass().getResourceAsStream("/testNetworkNodeBreakerWithoutExtensions.xiidm"));
LineAdder lineAdder = network.newLine()
.setId("lineTest")
.setR(1.0)
.setX(1.0)
.setG1(0.0)
.setG2(0.0)
.setB1(0.0)
.setB2(0.0);
ReportNode reportNode = ReportNode.newRootReportNode()
.withResourceBundles(PowsyblCoreTestReportResourceBundle.TEST_BASE_NAME, PowsyblCoreReportResourceBundle.BASE_NAME)
.withMessageTemplate("reportTestCreateLineWithoutExtensions")
.build();
new CreateBranchFeederBaysBuilder()
.withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("bbs5")
.withPositionOrder1(115)
.withDirection1(BOTTOM)
.withBusOrBusbarSectionId2("bbs1")
.withPositionOrder2(121)
.withDirection2(TOP)
.build()
.apply(network, true, reportNode);
testReportNode(reportNode, "/reportNode/create-line-NB-without-extensions-report.txt");
}
@Test
void testGetName() {
Network network = Network.read("testNetworkNodeBreakerWithoutExtensions.xiidm", getClass().getResourceAsStream("/testNetworkNodeBreakerWithoutExtensions.xiidm"));
LineAdder lineAdder = network.newLine()
.setId("lineTest")
.setR(1.0)
.setX(1.0)
.setG1(0.0)
.setG2(0.0)
.setB1(0.0)
.setB2(0.0);
AbstractNetworkModification networkModification = new CreateBranchFeederBaysBuilder()
.withBranchAdder(lineAdder)
.withBusOrBusbarSectionId1("bbs5")
.withPositionOrder1(115)
.withDirection1(BOTTOM)
.withBusOrBusbarSectionId2("bbs1")
.withPositionOrder2(121)
.withDirection2(TOP)
.build();
assertEquals("CreateBranchFeederBays", networkModification.getName());
}
}