Skip to content

Commit

Permalink
Added generator remote reactive power control iIDM extension XML seri…
Browse files Browse the repository at this point in the history
…alization (#2694)

* Added generator remote reactive power control iIDM extension XML serialization
* check version >= 1.5

Signed-off-by: Damien Jeandemange <damien.jeandemange@artelys.com>
  • Loading branch information
jeandemanged authored Sep 20, 2023
1 parent 8f130d6 commit 9a1312b
Show file tree
Hide file tree
Showing 15 changed files with 429 additions and 0 deletions.
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;

/**
* @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 {
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;
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"?>
<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

0 comments on commit 9a1312b

Please sign in to comment.