Skip to content

Commit

Permalink
CGMES extensions SerDe fixes (powsybl#3145)
Browse files Browse the repository at this point in the history
* Add binary write/read in cgmes extensions roundtrip unit tests
* Add binary read/write in entsoe roundrip unit test
* Enrich CgmesLineBoundaryNode unit test
* Fix CgmesLineBoundaryNode SerDe
* Fix CgmesDanglingLineBoundaryNode SerDe
* Fix CgmesTapChangers SerDe
* Fix BaseVoltageMapping SerDe
* Add CgmesDanglingLineBoundaryNode unit test
* Add CgmesTapChangers unit test
* Add BaseVoltageMapping unit test
* Rename private static method in unit tests
* Factorize duplicated code

Signed-off-by: Florian Dupuy <[email protected]>
  • Loading branch information
flo-dup authored Sep 23, 2024
1 parent f9a167d commit ddbef02
Show file tree
Hide file tree
Showing 14 changed files with 272 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ public BaseVoltageMapping read(Network extendable, DeserializerContext context)
context.getReader().readChildNodes(elementName -> {
if (elementName.equals(BASE_VOLTAGE_ROOT_ELEMENT)) {
double nominalV = context.getReader().readDoubleAttribute("nominalVoltage");
String sourceBV = context.getReader().readStringAttribute("source");
Source sourceBV = context.getReader().readEnumAttribute("source", Source.class);
String baseVoltageId = context.getReader().readStringAttribute("id");
context.getReader().readEndNode();
mapping.addBaseVoltage(nominalV, baseVoltageId, Source.valueOf(sourceBV));
mapping.addBaseVoltage(nominalV, baseVoltageId, sourceBV);
} else {
throw new PowsyblException("Unknown element name '" + elementName + "' in 'baseVoltageMapping'");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ public CgmesDanglingLineBoundaryNodeSerDe() {
@Override
public void write(CgmesDanglingLineBoundaryNode extension, SerializerContext context) {
context.getWriter().writeBooleanAttribute("isHvdc", extension.isHvdc());
extension.getLineEnergyIdentificationCodeEic().ifPresent(lineEnergyIdentificationCodeEic ->
context.getWriter().writeStringAttribute("lineEnergyIdentificationCodeEic", lineEnergyIdentificationCodeEic));
context.getWriter().writeStringAttribute("lineEnergyIdentificationCodeEic", extension.getLineEnergyIdentificationCodeEic().orElse(null));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ public CgmesLineBoundaryNodeSerDe() {
@Override
public void write(CgmesLineBoundaryNode extension, SerializerContext context) {
context.getWriter().writeBooleanAttribute("isHvdc", extension.isHvdc());
extension.getLineEnergyIdentificationCodeEic().ifPresent(lineEnergyIdentificationCodeEic ->
context.getWriter().writeStringAttribute("lineEnergyIdentificationCodeEic", lineEnergyIdentificationCodeEic));
context.getWriter().writeStringAttribute("lineEnergyIdentificationCodeEic", extension.getLineEnergyIdentificationCodeEic().orElse(null));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ public CgmesTapChangers<C> read(C extendable, DeserializerContext context) {
.setId(reader.readStringAttribute("id"))
.setCombinedTapChangerId(reader.readStringAttribute("combinedTapChangerId"))
.setType(reader.readStringAttribute("type"))
.setHiddenStatus(reader.readBooleanAttribute("hidden", false))
.setControlId(reader.readStringAttribute("controlId"));
.setHiddenStatus(reader.readBooleanAttribute("hidden", false));
reader.readOptionalIntAttribute("step").ifPresent(adder::setStep);
adder.setControlId(reader.readStringAttribute("controlId"));
context.getReader().readEndNode();
adder.add();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,23 @@
public abstract class AbstractCgmesExtensionTest extends AbstractSerDeTest {

protected void allFormatsRoundTripTest(Network network, String xmlRefFile) throws IOException {
roundTripXmlTest(network, this::jsonWriteAndRead, NetworkSerDe::write, NetworkSerDe::validateAndRead, xmlRefFile);
roundTripXmlTest(network,
(n, p) -> binWriteAndRead(jsonWriteAndRead(n, p), p),
NetworkSerDe::write,
NetworkSerDe::validateAndRead,
xmlRefFile);
}

private Network jsonWriteAndRead(Network network, Path path) {
private static Network binWriteAndRead(Network network, Path path) {
var anonymizer = NetworkSerDe.write(network, new ExportOptions().setFormat(TreeDataFormat.BIN), path);
try (InputStream is = Files.newInputStream(path)) {
return NetworkSerDe.read(is, new ImportOptions().setFormat(TreeDataFormat.BIN), anonymizer);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

private static Network jsonWriteAndRead(Network network, Path path) {
var anonymizer = NetworkSerDe.write(network, new ExportOptions().setFormat(TreeDataFormat.JSON), path);
try (InputStream is = Files.newInputStream(path)) {
return NetworkSerDe.read(is, new ImportOptions().setFormat(TreeDataFormat.JSON), anonymizer);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.cgmes.extensions;

import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.test.NoEquipmentNetworkFactory;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.time.ZonedDateTime;

/**
* @author Florian Dupuy {@literal <florian.dupuy at rte-france.com>}
*/
class BaseVoltageMappingSerDeTest extends AbstractCgmesExtensionTest {

@Test
void test() throws IOException {
Network network = NoEquipmentNetworkFactory.create();
network.setCaseDate(ZonedDateTime.parse("2024-09-17T13:36:37.831Z"));
network.newExtension(BaseVoltageMappingAdder.class)
.addBaseVoltage("id_400", 400, Source.IGM)
.addBaseVoltage("id_380", 380, Source.BOUNDARY)
.add();
allFormatsRoundTripTest(network, "/no_equipment_base_voltage_mapping.xml");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,34 @@
/**
* @author Miora Ralambotiana {@literal <miora.ralambotiana at rte-france.com>}
*/
class CgmesLineBoundaryNodeSerDeTest extends AbstractCgmesExtensionTest {
class CgmesBoundaryNodeSerDeTest extends AbstractCgmesExtensionTest {

@Test
void test() throws IOException {
void testTieLine() throws IOException {
Network network = EurostagTutorialExample1Factory.createWithTieLine();
network.getTieLine("NHV1_NHV2_1").newExtension(CgmesLineBoundaryNodeAdder.class)
.setHvdc(true)
.setLineEnergyIdentificationCodeEic("EIC_CODE")
.add();
network.getTieLine("NHV1_NHV2_2").newExtension(CgmesLineBoundaryNodeAdder.class)
.setHvdc(true)
.add();
allFormatsRoundTripTest(network, "/eurostag_cgmes_line_boundary_node.xml");
}

@Test
void testDanglingLine() throws IOException {
Network network = EurostagTutorialExample1Factory.createWithTieLine();
var tl = network.getTieLine("NHV1_NHV2_1");
tl.getDanglingLine1().newExtension(CgmesDanglingLineBoundaryNodeAdder.class)
.setHvdc(false)
.setLineEnergyIdentificationCodeEic("EIC_CODE")
.add();
tl.getDanglingLine2().newExtension(CgmesDanglingLineBoundaryNodeAdder.class)
.setHvdc(false)
.add();
tl.remove();

allFormatsRoundTripTest(network, "/eurostag_cgmes_dangling_line_boundary_node.xml");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.cgmes.extensions;

import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.ThreeWindingsTransformer;
import com.powsybl.iidm.network.TwoWindingsTransformer;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.time.ZonedDateTime;

/**
* @author Florian Dupuy {@literal <florian.dupuy at rte-france.com>}
*/
class CgmesTapChangersSerDeTest extends AbstractCgmesExtensionTest {

@Test
void test() throws IOException {
Network network = EurostagTutorialExample1Factory.createWith3wTransformer();
network.setCaseDate(ZonedDateTime.parse("2024-09-17T12:01:34.831Z"));
TwoWindingsTransformer twoWT = network.getTwoWindingsTransformer("NGEN_NHV1");
CgmesTapChangers<TwoWindingsTransformer> ctc2wt = ((CgmesTapChangersAdder<TwoWindingsTransformer>) twoWT.newExtension(CgmesTapChangersAdder.class)).add();
ctc2wt.newTapChanger()
.setId("tc1")
.setControlId("control1")
.setType("type1")
.setHiddenStatus(false)
.add();
ThreeWindingsTransformer threeWT = network.getThreeWindingsTransformer("NGEN_V2_NHV1");
CgmesTapChangers<ThreeWindingsTransformer> ctc3wt = ((CgmesTapChangersAdder<ThreeWindingsTransformer>) threeWT.newExtension(CgmesTapChangersAdder.class)).add();
ctc3wt.newTapChanger()
.setId("tc2")
.setCombinedTapChangerId("ctc2")
.setStep(1)
.setControlId("control2")
.setType("type2")
.setHiddenStatus(true)
.add();
allFormatsRoundTripTest(network, "/eurostag_cgmes_tap_changers.xml");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_13" xmlns:cdlbn="http://www.powsybl.org/schema/iidm/ext/cgmes_dangling_line_boundary_node/1_0" id="sim1" caseDate="2013-01-15T18:45:00.000+01:00" forecastDistance="0" sourceFormat="test" minimumValidationLevel="STEADY_STATE_HYPOTHESIS">
<iidm:substation id="P1" country="FR" tso="RTE" geographicalTags="A">
<iidm:voltageLevel id="VLGEN" nominalV="24.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NGEN" v="24.500000610351563" angle="2.3259763717651367"/>
</iidm:busBreakerTopology>
<iidm:generator id="GEN" energySource="OTHER" minP="-9999.99" maxP="9999.99" voltageRegulatorOn="true" targetP="607.0" targetV="24.5" targetQ="301.0" bus="NGEN" connectableBus="NGEN" p="-605.558349609375" q="-225.2825164794922">
<iidm:minMaxReactiveLimits minQ="-9999.99" maxQ="9999.99"/>
</iidm:generator>
</iidm:voltageLevel>
<iidm:voltageLevel id="VLHV1" nominalV="380.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NHV1" v="402.1428451538086" angle="0.0"/>
</iidm:busBreakerTopology>
<iidm:danglingLine id="NHV1_XNODE1" p0="0.0" q0="0.0" r="1.5" x="20.0" g="1.0E-6" b="1.93E-4" pairingKey="XNODE1" bus="NHV1" connectableBus="NHV1" p="302.4440612792969" q="98.74027252197266"/>
<iidm:danglingLine id="NVH1_XNODE2" p0="0.0" q0="0.0" r="1.5" x="20.0" g="1.0E-6" b="1.93E-4" pairingKey="XNODE2" bus="NHV1" connectableBus="NHV1" p="302.4440612792969" q="98.74027252197266"/>
</iidm:voltageLevel>
<iidm:twoWindingsTransformer id="NGEN_NHV1" r="0.26658461538461536" x="11.104492831516762" g="0.0" b="0.0" ratedU1="24.0" ratedU2="400.0" bus1="NGEN" connectableBus1="NGEN" voltageLevelId1="VLGEN" bus2="NHV1" connectableBus2="NHV1" voltageLevelId2="VLHV1" p1="605.558349609375" q1="225.2825164794922" p2="-604.8909301757812" q2="-197.48046875"/>
</iidm:substation>
<iidm:substation id="P2" country="FR" tso="RTE" geographicalTags="B">
<iidm:voltageLevel id="VLHV2" nominalV="380.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NHV2" v="389.9526763916016" angle="-3.5063576698303223"/>
</iidm:busBreakerTopology>
<iidm:danglingLine id="XNODE1_NHV2" p0="0.0" q0="0.0" r="1.5" x="13.0" g="2.0E-6" b="1.93E-4" pairingKey="XNODE1" bus="NHV2" connectableBus="NHV2" p="-300.43389892578125" q="-137.18849182128906"/>
<iidm:danglingLine id="XNODE2_NHV2" p0="0.0" q0="0.0" r="1.5" x="13.0" g="2.0E-6" b="1.93E-4" pairingKey="XNODE2" bus="NHV2" connectableBus="NHV2" p="-300.43389892578125" q="-137.18849182128906"/>
</iidm:voltageLevel>
<iidm:voltageLevel id="VLLOAD" nominalV="150.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NLOAD" v="147.57861328125" angle="-9.614486694335938"/>
</iidm:busBreakerTopology>
<iidm:load id="LOAD" loadType="UNDEFINED" p0="600.0" q0="200.0" bus="NLOAD" connectableBus="NLOAD" p="600.0" q="200.0"/>
</iidm:voltageLevel>
<iidm:twoWindingsTransformer id="NHV2_NLOAD" r="0.04724999999999999" x="4.049724365620455" g="0.0" b="0.0" ratedU1="400.0" ratedU2="158.0" bus1="NHV2" connectableBus1="NHV2" voltageLevelId1="VLHV2" bus2="NLOAD" connectableBus2="NLOAD" voltageLevelId2="VLLOAD" p1="600.8677978515625" q1="274.3769836425781" p2="-600.0" q2="-200.0">
<iidm:ratioTapChanger lowTapPosition="0" tapPosition="1" targetDeadband="0.0" loadTapChangingCapabilities="true" regulating="true" regulationMode="VOLTAGE" regulationValue="158.0">
<iidm:terminalRef id="NHV2_NLOAD" side="TWO"/>
<iidm:step r="0.0" x="0.0" g="0.0" b="0.0" rho="0.8505666905244191"/>
<iidm:step r="0.0" x="0.0" g="0.0" b="0.0" rho="1.0006666666666666"/>
<iidm:step r="0.0" x="0.0" g="0.0" b="0.0" rho="1.150766642808914"/>
</iidm:ratioTapChanger>
</iidm:twoWindingsTransformer>
</iidm:substation>
<iidm:tieLine id="NHV1_NHV2_2" danglingLineId1="NVH1_XNODE2" danglingLineId2="XNODE2_NHV2"/>
<iidm:extension id="XNODE1_NHV2">
<cdlbn:cgmesDanglingLineBoundaryNode isHvdc="false"/>
</iidm:extension>
<iidm:extension id="NHV1_XNODE1">
<cdlbn:cgmesDanglingLineBoundaryNode isHvdc="false" lineEnergyIdentificationCodeEic="EIC_CODE"/>
</iidm:extension>
</iidm:network>
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
</iidm:substation>
<iidm:tieLine id="NHV1_NHV2_1" danglingLineId1="NHV1_XNODE1" danglingLineId2="XNODE1_NHV2"/>
<iidm:tieLine id="NHV1_NHV2_2" danglingLineId1="NVH1_XNODE2" danglingLineId2="XNODE2_NHV2"/>
<iidm:extension id="NHV1_NHV2_2">
<clbn:cgmesLineBoundaryNode isHvdc="true"/>
</iidm:extension>
<iidm:extension id="NHV1_NHV2_1">
<clbn:cgmesLineBoundaryNode isHvdc="true" lineEnergyIdentificationCodeEic="EIC_CODE"/>
</iidm:extension>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_13" xmlns:ctc="http://www.powsybl.org/schema/iidm/ext/cgmes_tap_changers/1_0" id="sim1" caseDate="2024-09-17T12:01:34.831Z" forecastDistance="0" sourceFormat="test" minimumValidationLevel="STEADY_STATE_HYPOTHESIS">
<iidm:substation id="P1" country="FR" tso="RTE" geographicalTags="A">
<iidm:voltageLevel id="VLGEN" nominalV="24.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NGEN"/>
</iidm:busBreakerTopology>
<iidm:generator id="GEN" energySource="OTHER" minP="-9999.99" maxP="9999.99" voltageRegulatorOn="true" targetP="607.0" targetV="24.5" targetQ="301.0" bus="NGEN" connectableBus="NGEN">
<iidm:minMaxReactiveLimits minQ="-9999.99" maxQ="9999.99"/>
</iidm:generator>
</iidm:voltageLevel>
<iidm:voltageLevel id="VLHV1" nominalV="380.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NHV1"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
<iidm:voltageLevel id="V2" nominalV="150.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="N2"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
<iidm:twoWindingsTransformer id="NGEN_NHV1" r="0.26658461538461536" x="11.104492831516762" g="0.0" b="0.0" ratedU1="24.0" ratedU2="400.0" voltageLevelId1="VLGEN" bus1="NGEN" connectableBus1="NGEN" voltageLevelId2="VLHV1" bus2="NHV1" connectableBus2="NHV1"/>
<iidm:threeWindingsTransformer id="NGEN_V2_NHV1" r1="0.001" x1="1.0E-6" g1="0.0" b1="0.0" ratedU1="400.0" r2="0.1" x2="1.0E-5" g2="0.0" b2="0.0" ratedU2="150.0" r3="0.01" x3="1.0E-4" g3="0.0" b3="0.0" ratedU3="24.0" ratedU0="400.0" voltageLevelId1="VLHV1" bus1="NHV1" connectableBus1="NHV1" voltageLevelId2="V2" bus2="N2" connectableBus2="N2" voltageLevelId3="VLGEN" bus3="NGEN" connectableBus3="NGEN"/>
</iidm:substation>
<iidm:substation id="P2" country="FR" tso="RTE" geographicalTags="B">
<iidm:voltageLevel id="VLHV2" nominalV="380.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NHV2"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
<iidm:voltageLevel id="VLLOAD" nominalV="150.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NLOAD"/>
</iidm:busBreakerTopology>
<iidm:load id="LOAD" loadType="UNDEFINED" p0="600.0" q0="200.0" bus="NLOAD" connectableBus="NLOAD"/>
</iidm:voltageLevel>
</iidm:substation>
<iidm:line id="NHV1_NHV2_1" r="3.0" x="33.0" g1="0.0" b1="1.93E-4" g2="0.0" b2="1.93E-4" voltageLevelId1="VLHV1" bus1="NHV1" connectableBus1="NHV1" voltageLevelId2="VLHV2" bus2="NHV2" connectableBus2="NHV2"/>
<iidm:line id="NHV1_NHV2_2" r="3.0" x="33.0" g1="0.0" b1="1.93E-4" g2="0.0" b2="1.93E-4" voltageLevelId1="VLHV1" bus1="NHV1" connectableBus1="NHV1" voltageLevelId2="VLHV2" bus2="NHV2" connectableBus2="NHV2"/>
<iidm:extension id="NGEN_NHV1">
<ctc:cgmesTapChangers>
<ctc:tapChanger id="tc1" type="type1" controlId="control1"/>
</ctc:cgmesTapChangers>
</iidm:extension>
<iidm:extension id="NGEN_V2_NHV1">
<ctc:cgmesTapChangers>
<ctc:tapChanger id="tc2" combinedTapChangerId="ctc2" type="type2" hidden="true" step="1" controlId="control2"/>
</ctc:cgmesTapChangers>
</iidm:extension>
</iidm:network>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_13" xmlns:bv="http://www.powsybl.org/schema/iidm/ext/base_voltage_mapping/1_0" id="test" caseDate="2024-09-17T13:36:37.831Z" forecastDistance="0" sourceFormat="test" minimumValidationLevel="STEADY_STATE_HYPOTHESIS">
<iidm:substation id="sub" country="FR" tso="RTE">
<iidm:voltageLevel id="vl1" name="vl1" nominalV="440.0" lowVoltageLimit="200.0" highVoltageLimit="400.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="busA" name="busA"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
<iidm:voltageLevel id="vl2" name="vl2" nominalV="200.0" lowVoltageLimit="200.0" highVoltageLimit="400.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="busB" name="busB"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
</iidm:substation>
<iidm:extension id="test">
<bv:baseVoltageMapping>
<bv:baseVoltage nominalVoltage="380.0" source="BOUNDARY" id="id_380"/>
<bv:baseVoltage nominalVoltage="400.0" source="IGM" id="id_400"/>
</bv:baseVoltageMapping>
</iidm:extension>
</iidm:network>
Loading

0 comments on commit ddbef02

Please sign in to comment.