Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added generator remote reactive power control iIDM extension XML serialization #2694

Merged
merged 12 commits into from
Sep 20, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright (c) 2023, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/)
* 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 com.powsybl.iidm.xml.extensions;

import com.google.auto.service.AutoService;
import com.powsybl.commons.extensions.AbstractExtensionXmlSerializer;
import com.powsybl.commons.extensions.ExtensionXmlSerializer;
import com.powsybl.commons.xml.XmlReaderContext;
import com.powsybl.commons.xml.XmlUtil;
import com.powsybl.commons.xml.XmlWriterContext;
import com.powsybl.iidm.network.Generator;
import com.powsybl.iidm.network.Terminal;
import com.powsybl.iidm.network.extensions.RemoteReactivePowerControl;
import com.powsybl.iidm.network.extensions.RemoteReactivePowerControlAdder;
import com.powsybl.iidm.xml.IidmXmlVersion;
import com.powsybl.iidm.xml.NetworkXmlReaderContext;
import com.powsybl.iidm.xml.NetworkXmlWriterContext;
import com.powsybl.iidm.xml.TerminalRefXml;
import com.powsybl.iidm.xml.util.IidmXmlUtil;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

jeandemanged marked this conversation as resolved.
Show resolved Hide resolved
/**
* @author Damien Jeandemange <damien.jeandemange at artelys.com>
*/
@AutoService(ExtensionXmlSerializer.class)
public class RemoteReactivePowerControlXmlSerializer extends AbstractExtensionXmlSerializer<Generator, RemoteReactivePowerControl> {

public RemoteReactivePowerControlXmlSerializer() {
super(RemoteReactivePowerControl.NAME, "network", RemoteReactivePowerControl.class, false,
"remoteReactivePowerControl_V1_0.xsd", "http://www.powsybl.org/schema/iidm/ext/remote_reactive_power_control/1_0", "rrpc");
}

@Override
public void write(RemoteReactivePowerControl extension, XmlWriterContext context) throws XMLStreamException {
Copy link
Member

Choose a reason for hiding this comment

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

According to @geofjamg, the fact that we added this extension without any serialization (PR #1732) should be considered as an issue. So we have to support your new features since version 1.5.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agree, adjusted PR description accordingly.
I wasn't too familiar with iIDM XML versioning, could you please check if this is done right now ? @annetill @geofjamg

NetworkXmlWriterContext networkContext = (NetworkXmlWriterContext) context;
IidmXmlUtil.assertMinimumVersion(getName(), IidmXmlUtil.ErrorMessage.NOT_SUPPORTED, IidmXmlVersion.V_1_5, networkContext);
XMLStreamWriter writer = context.getWriter();
writer.writeAttribute("enabled", Boolean.toString(extension.isEnabled()));
XmlUtil.writeDouble("targetQ", extension.getTargetQ(), writer);
TerminalRefXml.writeTerminalRefAttribute(extension.getRegulatingTerminal(), networkContext);
}

@Override
public RemoteReactivePowerControl read(Generator extendable, XmlReaderContext context) throws XMLStreamException {
NetworkXmlReaderContext networkContext = (NetworkXmlReaderContext) context;
jeandemanged marked this conversation as resolved.
Show resolved Hide resolved
IidmXmlUtil.assertMinimumVersion(getName(), IidmXmlUtil.ErrorMessage.NOT_SUPPORTED, IidmXmlVersion.V_1_5, networkContext);
boolean enabled = XmlUtil.readBoolAttribute(context.getReader(), "enabled");
double targetQ = XmlUtil.readDoubleAttribute(context.getReader(), "targetQ");
Terminal terminal = TerminalRefXml.readTerminal(networkContext, extendable.getNetwork());
return extendable.newExtension(RemoteReactivePowerControlAdder.class)
.withEnabled(enabled)
.withTargetQ(targetQ)
.withRegulatingTerminal(terminal)
.add();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (c) 2023, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/)
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

-->
<xs:schema version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:iidm="http://www.powsybl.org/schema/iidm/1_10"
targetNamespace="http://www.powsybl.org/schema/iidm/ext/remote_reactive_power_control/1_0"
elementFormDefault="qualified">
<xs:import namespace="http://www.powsybl.org/schema/iidm/1_10" schemaLocation="iidm_V1_10.xsd"/>
<xs:element name="generatorRemoteReactivePowerControl">
<xs:complexType>
<xs:attribute name="enabled" use="required" type="xs:boolean"/>
<xs:attribute name="targetQ" use="required" type="xs:double"/>
<xs:attribute name="id" use="required" type="iidm:nonEmptyString"/>
<xs:attribute name="side" type="iidm:Side"/>
</xs:complexType>
</xs:element>
</xs:schema>
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/**
* Copyright (c) 2023, Coreso SA (https://www.coreso.eu/) and TSCNET Services GmbH (https://www.tscnet.eu/)
* 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 com.powsybl.iidm.xml.extensions;

import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.RemoteReactivePowerControl;
import com.powsybl.iidm.network.extensions.RemoteReactivePowerControlAdder;
import com.powsybl.iidm.xml.*;
import org.joda.time.DateTime;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;

import static org.junit.jupiter.api.Assertions.*;

/**
* @author Damien Jeandemange <damien.jeandemange at artelys.com>
*/
class RemoteReactivePowerControlXmlTest extends AbstractXmlConverterTest {

private static Network createTestNetwork() {
// network for serialization test purposes only, no load-flow would converge on this.
Network network = Network.create("test", "test");
network.setCaseDate(DateTime.parse("2016-06-27T12:27:58.535+02:00"));
Substation s = network.newSubstation()
.setId("S")
.setCountry(Country.FR)
.add();
VoltageLevel vl = s.newVoltageLevel()
.setId("VL")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
vl.getBusBreakerView().newBus()
.setId("B1")
.add();
vl.getBusBreakerView().newBus()
.setId("B2")
.add();
var gen = vl.newGenerator()
.setId("G")
.setBus("B1")
.setConnectableBus("B1")
.setTargetP(100)
.setTargetQ(100)
.setTargetV(400)
.setMinP(0)
.setMaxP(200)
.setVoltageRegulatorOn(true)
.add();
var line = network.newLine()
.setId("L12")
.setVoltageLevel1("VL").setBus1("B1")
.setVoltageLevel2("VL").setBus2("B2")
.setR(0).setX(1).setB1(0).setB2(0).setG1(0).setG2(0)
.add();

gen.newExtension(RemoteReactivePowerControlAdder.class)
.withEnabled(true)
.withTargetQ(123)
.withRegulatingTerminal(line.getTerminal2())
.add();
return network;
}

@Test
void test() throws IOException {
Network network = createTestNetwork();

RemoteReactivePowerControl rrpc = network.getGenerator("G").getExtension(RemoteReactivePowerControl.class);
assertNotNull(rrpc);

Network network2 = roundTripXmlTest(network,
NetworkXml::writeAndValidate,
NetworkXml::read,
getVersionDir(IidmXmlConstants.CURRENT_IIDM_XML_VERSION) + "remoteReactivePowerControlRef.xml");

Generator gen2 = network2.getGenerator("G");
Line line = network.getLine("L12");
Line line2 = network2.getLine("L12");
assertNotNull(gen2);
RemoteReactivePowerControl rrpc2 = gen2.getExtension(RemoteReactivePowerControl.class);
assertNotNull(rrpc2);
assertEquals(rrpc.isEnabled(), rrpc2.isEnabled());
assertEquals(rrpc.getTargetQ(), rrpc2.getTargetQ(), 0f);
assertEquals(rrpc.getRegulatingTerminal().getConnectable().getId(), rrpc2.getRegulatingTerminal().getConnectable().getId());
assertEquals(line.getSide(rrpc.getRegulatingTerminal()), line2.getSide(rrpc2.getRegulatingTerminal()));

// backward compatibility checks from version 1.5
roundTripVersionedXmlFromMinToCurrentVersionTest("remoteReactivePowerControlRef.xml", IidmXmlVersion.V_1_5);

// check it fails for all versions < 1.5
testForAllPreviousVersions(IidmXmlVersion.V_1_5, version -> {
ExportOptions options = new ExportOptions().setVersion(version.toString("."));
Path path = tmpDir.resolve("fail");
try {
NetworkXml.write(network, options, path);
fail();
} catch (PowsyblException e) {
assertEquals("generatorRemoteReactivePowerControl is not supported for IIDM-XML version " + version.toString(".") + ". IIDM-XML version should be >= 1.5", e.getMessage());
}
});

// check it doesn't fail for all versions < 1.5 if IidmVersionIncompatibilityBehavior is to log error
testForAllPreviousVersions(IidmXmlVersion.V_1_5, version -> {
try {
writeXmlTest(network, (n, path) -> write(n, path, version), getVersionedNetworkPath("remoteReactivePowerControlNotSupported.xml", version));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}

private static void write(Network network, Path path, IidmXmlVersion version) {
ExportOptions options = new ExportOptions().setIidmVersionIncompatibilityBehavior(ExportOptions.IidmVersionIncompatibilityBehavior.LOG_ERROR)
.setVersion(version.toString("."));
NetworkXml.write(network, options, path);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
Copy link
Member

Choose a reason for hiding this comment

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

Not sure it is necessary to test for all versions until 1.0 ? But it is done now.

<iidm:network xmlns:iidm="http://www.itesla_project.eu/schema/iidm/1_0" xmlns:rrpc="http://www.powsybl.org/schema/iidm/ext/remote_reactive_power_control/1_0" id="test" caseDate="2016-06-27T12:27:58.535+02:00" forecastDistance="0" sourceFormat="test">
<iidm:substation id="S" country="FR">
<iidm:voltageLevel id="VL" nominalV="400.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="B1"/>
<iidm:bus id="B2"/>
</iidm:busBreakerTopology>
<iidm:generator id="G" energySource="OTHER" minP="0.0" maxP="200.0" voltageRegulatorOn="true" targetP="100.0" targetV="400.0" targetQ="100.0" bus="B1" connectableBus="B1">
<iidm:minMaxReactiveLimits minQ="-1.7976931348623157E308" maxQ="1.7976931348623157E308"/>
</iidm:generator>
</iidm:voltageLevel>
</iidm:substation>
<iidm:line id="L12" r="0.0" x="1.0" g1="0.0" b1="0.0" g2="0.0" b2="0.0" bus1="B1" connectableBus1="B1" voltageLevelId1="VL" bus2="B2" connectableBus2="B2" voltageLevelId2="VL"/>
<iidm:extension id="G">
<rrpc:generatorRemoteReactivePowerControl enabled="true" targetQ="123.0" id="L12" side="TWO"/>
</iidm:extension>
</iidm:network>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_1" xmlns:rrpc="http://www.powsybl.org/schema/iidm/ext/remote_reactive_power_control/1_0" id="test" caseDate="2016-06-27T12:27:58.535+02:00" forecastDistance="0" sourceFormat="test">
<iidm:substation id="S" country="FR">
<iidm:voltageLevel id="VL" nominalV="400.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="B1"/>
<iidm:bus id="B2"/>
</iidm:busBreakerTopology>
<iidm:generator id="G" energySource="OTHER" minP="0.0" maxP="200.0" voltageRegulatorOn="true" targetP="100.0" targetV="400.0" targetQ="100.0" bus="B1" connectableBus="B1">
<iidm:minMaxReactiveLimits minQ="-1.7976931348623157E308" maxQ="1.7976931348623157E308"/>
</iidm:generator>
</iidm:voltageLevel>
</iidm:substation>
<iidm:line id="L12" r="0.0" x="1.0" g1="0.0" b1="0.0" g2="0.0" b2="0.0" bus1="B1" connectableBus1="B1" voltageLevelId1="VL" bus2="B2" connectableBus2="B2" voltageLevelId2="VL"/>
<iidm:extension id="G">
<rrpc:generatorRemoteReactivePowerControl enabled="true" targetQ="123.0" id="L12" side="TWO"/>
</iidm:extension>
</iidm:network>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_10" xmlns:rrpc="http://www.powsybl.org/schema/iidm/ext/remote_reactive_power_control/1_0" id="test" caseDate="2016-06-27T12:27:58.535+02:00" forecastDistance="0" sourceFormat="test" minimumValidationLevel="STEADY_STATE_HYPOTHESIS">
<iidm:substation id="S" country="FR">
<iidm:voltageLevel id="VL" nominalV="400.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="B1"/>
<iidm:bus id="B2"/>
</iidm:busBreakerTopology>
<iidm:generator id="G" energySource="OTHER" minP="0.0" maxP="200.0" voltageRegulatorOn="true" targetP="100.0" targetV="400.0" targetQ="100.0" bus="B1" connectableBus="B1">
<iidm:minMaxReactiveLimits minQ="-1.7976931348623157E308" maxQ="1.7976931348623157E308"/>
</iidm:generator>
</iidm:voltageLevel>
</iidm:substation>
<iidm:line id="L12" r="0.0" x="1.0" g1="0.0" b1="0.0" g2="0.0" b2="0.0" bus1="B1" connectableBus1="B1" voltageLevelId1="VL" bus2="B2" connectableBus2="B2" voltageLevelId2="VL"/>
<iidm:extension id="G">
<rrpc:generatorRemoteReactivePowerControl enabled="true" targetQ="123.0" id="L12" side="TWO"/>
</iidm:extension>
</iidm:network>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_11" xmlns:rrpc="http://www.powsybl.org/schema/iidm/ext/remote_reactive_power_control/1_0" id="test" caseDate="2016-06-27T12:27:58.535+02:00" forecastDistance="0" sourceFormat="test" minimumValidationLevel="STEADY_STATE_HYPOTHESIS">
<iidm:substation id="S" country="FR">
<iidm:voltageLevel id="VL" nominalV="400.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="B1"/>
<iidm:bus id="B2"/>
</iidm:busBreakerTopology>
<iidm:generator id="G" energySource="OTHER" minP="0.0" maxP="200.0" voltageRegulatorOn="true" targetP="100.0" targetV="400.0" targetQ="100.0" bus="B1" connectableBus="B1">
<iidm:minMaxReactiveLimits minQ="-1.7976931348623157E308" maxQ="1.7976931348623157E308"/>
</iidm:generator>
</iidm:voltageLevel>
</iidm:substation>
<iidm:line id="L12" r="0.0" x="1.0" g1="0.0" b1="0.0" g2="0.0" b2="0.0" bus1="B1" connectableBus1="B1" voltageLevelId1="VL" bus2="B2" connectableBus2="B2" voltageLevelId2="VL"/>
<iidm:extension id="G">
<rrpc:generatorRemoteReactivePowerControl enabled="true" targetQ="123.0" id="L12" side="TWO"/>
</iidm:extension>
</iidm:network>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_2" xmlns:rrpc="http://www.powsybl.org/schema/iidm/ext/remote_reactive_power_control/1_0" id="test" caseDate="2016-06-27T12:27:58.535+02:00" forecastDistance="0" sourceFormat="test">
<iidm:substation id="S" country="FR">
<iidm:voltageLevel id="VL" nominalV="400.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="B1"/>
<iidm:bus id="B2"/>
</iidm:busBreakerTopology>
<iidm:generator id="G" energySource="OTHER" minP="0.0" maxP="200.0" voltageRegulatorOn="true" targetP="100.0" targetV="400.0" targetQ="100.0" bus="B1" connectableBus="B1">
<iidm:minMaxReactiveLimits minQ="-1.7976931348623157E308" maxQ="1.7976931348623157E308"/>
</iidm:generator>
</iidm:voltageLevel>
</iidm:substation>
<iidm:line id="L12" r="0.0" x="1.0" g1="0.0" b1="0.0" g2="0.0" b2="0.0" bus1="B1" connectableBus1="B1" voltageLevelId1="VL" bus2="B2" connectableBus2="B2" voltageLevelId2="VL"/>
<iidm:extension id="G">
<rrpc:generatorRemoteReactivePowerControl enabled="true" targetQ="123.0" id="L12" side="TWO"/>
</iidm:extension>
</iidm:network>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_3" xmlns:rrpc="http://www.powsybl.org/schema/iidm/ext/remote_reactive_power_control/1_0" id="test" caseDate="2016-06-27T12:27:58.535+02:00" forecastDistance="0" sourceFormat="test">
<iidm:substation id="S" country="FR">
<iidm:voltageLevel id="VL" nominalV="400.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="B1"/>
<iidm:bus id="B2"/>
</iidm:busBreakerTopology>
<iidm:generator id="G" energySource="OTHER" minP="0.0" maxP="200.0" voltageRegulatorOn="true" targetP="100.0" targetV="400.0" targetQ="100.0" bus="B1" connectableBus="B1">
<iidm:minMaxReactiveLimits minQ="-1.7976931348623157E308" maxQ="1.7976931348623157E308"/>
</iidm:generator>
</iidm:voltageLevel>
</iidm:substation>
<iidm:line id="L12" r="0.0" x="1.0" g1="0.0" b1="0.0" g2="0.0" b2="0.0" bus1="B1" connectableBus1="B1" voltageLevelId1="VL" bus2="B2" connectableBus2="B2" voltageLevelId2="VL"/>
<iidm:extension id="G">
<rrpc:generatorRemoteReactivePowerControl enabled="true" targetQ="123.0" id="L12" side="TWO"/>
</iidm:extension>
</iidm:network>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_4" xmlns:rrpc="http://www.powsybl.org/schema/iidm/ext/remote_reactive_power_control/1_0" id="test" caseDate="2016-06-27T12:27:58.535+02:00" forecastDistance="0" sourceFormat="test">
<iidm:substation id="S" country="FR">
<iidm:voltageLevel id="VL" nominalV="400.0" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="B1"/>
<iidm:bus id="B2"/>
</iidm:busBreakerTopology>
<iidm:generator id="G" energySource="OTHER" minP="0.0" maxP="200.0" voltageRegulatorOn="true" targetP="100.0" targetV="400.0" targetQ="100.0" bus="B1" connectableBus="B1">
<iidm:minMaxReactiveLimits minQ="-1.7976931348623157E308" maxQ="1.7976931348623157E308"/>
</iidm:generator>
</iidm:voltageLevel>
</iidm:substation>
<iidm:line id="L12" r="0.0" x="1.0" g1="0.0" b1="0.0" g2="0.0" b2="0.0" bus1="B1" connectableBus1="B1" voltageLevelId1="VL" bus2="B2" connectableBus2="B2" voltageLevelId2="VL"/>
<iidm:extension id="G">
<rrpc:generatorRemoteReactivePowerControl enabled="true" targetQ="123.0" id="L12" side="TWO"/>
</iidm:extension>
</iidm:network>
Loading