From 9a1312b3dfcd7e687a4d7cfc2a6dd4f662e7ff29 Mon Sep 17 00:00:00 2001 From: jeandemanged <33569483+jeandemanged@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:22:58 +0200 Subject: [PATCH] Added generator remote reactive power control iIDM extension XML serialization (#2694) * Added generator remote reactive power control iIDM extension XML serialization * check version >= 1.5 Signed-off-by: Damien Jeandemange --- ...moteReactivePowerControlXmlSerializer.java | 62 +++++++++ .../xsd/remoteReactivePowerControl_V1_0.xsd | 25 ++++ .../RemoteReactivePowerControlXmlTest.java | 126 ++++++++++++++++++ ...remoteReactivePowerControlNotSupported.xml | 18 +++ ...remoteReactivePowerControlNotSupported.xml | 18 +++ .../V1_10/remoteReactivePowerControlRef.xml | 18 +++ .../V1_11/remoteReactivePowerControlRef.xml | 18 +++ ...remoteReactivePowerControlNotSupported.xml | 18 +++ ...remoteReactivePowerControlNotSupported.xml | 18 +++ ...remoteReactivePowerControlNotSupported.xml | 18 +++ .../V1_5/remoteReactivePowerControlRef.xml | 18 +++ .../V1_6/remoteReactivePowerControlRef.xml | 18 +++ .../V1_7/remoteReactivePowerControlRef.xml | 18 +++ .../V1_8/remoteReactivePowerControlRef.xml | 18 +++ .../V1_9/remoteReactivePowerControlRef.xml | 18 +++ 15 files changed, 429 insertions(+) create mode 100644 iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/extensions/RemoteReactivePowerControlXmlSerializer.java create mode 100644 iidm/iidm-xml-converter/src/main/resources/xsd/remoteReactivePowerControl_V1_0.xsd create mode 100644 iidm/iidm-xml-converter/src/test/java/com/powsybl/iidm/xml/extensions/RemoteReactivePowerControlXmlTest.java create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_0/remoteReactivePowerControlNotSupported.xml create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_1/remoteReactivePowerControlNotSupported.xml create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_10/remoteReactivePowerControlRef.xml create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_11/remoteReactivePowerControlRef.xml create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_2/remoteReactivePowerControlNotSupported.xml create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_3/remoteReactivePowerControlNotSupported.xml create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_4/remoteReactivePowerControlNotSupported.xml create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_5/remoteReactivePowerControlRef.xml create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_6/remoteReactivePowerControlRef.xml create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_7/remoteReactivePowerControlRef.xml create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_8/remoteReactivePowerControlRef.xml create mode 100644 iidm/iidm-xml-converter/src/test/resources/V1_9/remoteReactivePowerControlRef.xml diff --git a/iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/extensions/RemoteReactivePowerControlXmlSerializer.java b/iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/extensions/RemoteReactivePowerControlXmlSerializer.java new file mode 100644 index 00000000000..1c05c9fed39 --- /dev/null +++ b/iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/extensions/RemoteReactivePowerControlXmlSerializer.java @@ -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 + */ +@AutoService(ExtensionXmlSerializer.class) +public class RemoteReactivePowerControlXmlSerializer extends AbstractExtensionXmlSerializer { + + 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(); + } +} diff --git a/iidm/iidm-xml-converter/src/main/resources/xsd/remoteReactivePowerControl_V1_0.xsd b/iidm/iidm-xml-converter/src/main/resources/xsd/remoteReactivePowerControl_V1_0.xsd new file mode 100644 index 00000000000..3d64bb9a485 --- /dev/null +++ b/iidm/iidm-xml-converter/src/main/resources/xsd/remoteReactivePowerControl_V1_0.xsd @@ -0,0 +1,25 @@ + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/java/com/powsybl/iidm/xml/extensions/RemoteReactivePowerControlXmlTest.java b/iidm/iidm-xml-converter/src/test/java/com/powsybl/iidm/xml/extensions/RemoteReactivePowerControlXmlTest.java new file mode 100644 index 00000000000..1c82808e62b --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/java/com/powsybl/iidm/xml/extensions/RemoteReactivePowerControlXmlTest.java @@ -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 + */ +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); + } +} diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_0/remoteReactivePowerControlNotSupported.xml b/iidm/iidm-xml-converter/src/test/resources/V1_0/remoteReactivePowerControlNotSupported.xml new file mode 100644 index 00000000000..b7e3c18c213 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_0/remoteReactivePowerControlNotSupported.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_1/remoteReactivePowerControlNotSupported.xml b/iidm/iidm-xml-converter/src/test/resources/V1_1/remoteReactivePowerControlNotSupported.xml new file mode 100644 index 00000000000..9b70b382401 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_1/remoteReactivePowerControlNotSupported.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_10/remoteReactivePowerControlRef.xml b/iidm/iidm-xml-converter/src/test/resources/V1_10/remoteReactivePowerControlRef.xml new file mode 100644 index 00000000000..0a7af586a3b --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_10/remoteReactivePowerControlRef.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_11/remoteReactivePowerControlRef.xml b/iidm/iidm-xml-converter/src/test/resources/V1_11/remoteReactivePowerControlRef.xml new file mode 100644 index 00000000000..5949f18816d --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_11/remoteReactivePowerControlRef.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_2/remoteReactivePowerControlNotSupported.xml b/iidm/iidm-xml-converter/src/test/resources/V1_2/remoteReactivePowerControlNotSupported.xml new file mode 100644 index 00000000000..4f688f104a2 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_2/remoteReactivePowerControlNotSupported.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_3/remoteReactivePowerControlNotSupported.xml b/iidm/iidm-xml-converter/src/test/resources/V1_3/remoteReactivePowerControlNotSupported.xml new file mode 100644 index 00000000000..45d0d2f58ed --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_3/remoteReactivePowerControlNotSupported.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_4/remoteReactivePowerControlNotSupported.xml b/iidm/iidm-xml-converter/src/test/resources/V1_4/remoteReactivePowerControlNotSupported.xml new file mode 100644 index 00000000000..b16a51200b4 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_4/remoteReactivePowerControlNotSupported.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_5/remoteReactivePowerControlRef.xml b/iidm/iidm-xml-converter/src/test/resources/V1_5/remoteReactivePowerControlRef.xml new file mode 100644 index 00000000000..00ece32430e --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_5/remoteReactivePowerControlRef.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_6/remoteReactivePowerControlRef.xml b/iidm/iidm-xml-converter/src/test/resources/V1_6/remoteReactivePowerControlRef.xml new file mode 100644 index 00000000000..159031436a0 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_6/remoteReactivePowerControlRef.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_7/remoteReactivePowerControlRef.xml b/iidm/iidm-xml-converter/src/test/resources/V1_7/remoteReactivePowerControlRef.xml new file mode 100644 index 00000000000..73c78594fa6 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_7/remoteReactivePowerControlRef.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_8/remoteReactivePowerControlRef.xml b/iidm/iidm-xml-converter/src/test/resources/V1_8/remoteReactivePowerControlRef.xml new file mode 100644 index 00000000000..c8338ccd3ee --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_8/remoteReactivePowerControlRef.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_9/remoteReactivePowerControlRef.xml b/iidm/iidm-xml-converter/src/test/resources/V1_9/remoteReactivePowerControlRef.xml new file mode 100644 index 00000000000..fde54ed91b4 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_9/remoteReactivePowerControlRef.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + +