Skip to content

Commit

Permalink
Add 'withAutomationSystems' export option
Browse files Browse the repository at this point in the history
Signed-off-by: Olivier Perrin <olivier.perrin@rte-france.com>
  • Loading branch information
olperr1 committed Jan 10, 2024
1 parent c695977 commit 86ec61f
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@
* <td>version in which files will be generated</td>
* <td>1.5 or 1.4 etc</td>
* </tr>
* <tr>
* <td>iidm.export.xml.with-automation-systems</td>
* <td>if true automation systems are exported</td>
* <td>true or false</td>
* </tr>
* </table>
*
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
Expand All @@ -109,6 +114,7 @@ public abstract class AbstractTreeDataExporter implements Exporter {
public static final String EXTENSIONS_LIST = "iidm.export.xml.extensions";
public static final String SORTED = "iidm.export.xml.sorted";
public static final String VERSION = "iidm.export.xml.version";
public static final String WITH_AUTOMATION_SYSTEMS = "iidm.export.xml.with-automation-systems";

private static final Parameter INDENT_PARAMETER = new Parameter(INDENT, ParameterType.BOOLEAN, "Indent export output file", Boolean.TRUE);
private static final Parameter WITH_BRANCH_STATE_VARIABLES_PARAMETER = new Parameter(WITH_BRANCH_STATE_VARIABLES, ParameterType.BOOLEAN, "Export network with branch state variables", Boolean.TRUE);
Expand All @@ -126,11 +132,12 @@ public abstract class AbstractTreeDataExporter implements Exporter {
private static final Parameter SORTED_PARAMETER = new Parameter(SORTED, ParameterType.BOOLEAN, "Sort export output file", Boolean.FALSE);
private static final Parameter VERSION_PARAMETER = new Parameter(VERSION, ParameterType.STRING, "IIDM version in which files will be generated", IidmSerDeConstants.CURRENT_IIDM_VERSION.toString("."),
Arrays.stream(IidmVersion.values()).map(v -> v.toString(".")).collect(Collectors.toList()));

private static final Parameter WITH_AUTOMATION_SYSTEMS_PARAMETER = new Parameter(WITH_AUTOMATION_SYSTEMS, ParameterType.BOOLEAN,
"Export network with automation systems", Boolean.TRUE);
private static final List<Parameter> STATIC_PARAMETERS = List.of(INDENT_PARAMETER, WITH_BRANCH_STATE_VARIABLES_PARAMETER,
ONLY_MAIN_CC_PARAMETER, ANONYMISED_PARAMETER, IIDM_VERSION_INCOMPATIBILITY_BEHAVIOR_PARAMETER,
TOPOLOGY_LEVEL_PARAMETER, THROW_EXCEPTION_IF_EXTENSION_NOT_FOUND_PARAMETER, EXTENSIONS_LIST_PARAMETER,
SORTED_PARAMETER, VERSION_PARAMETER);
SORTED_PARAMETER, VERSION_PARAMETER, WITH_AUTOMATION_SYSTEMS_PARAMETER);

private final ParameterDefaultValueConfig defaultValueConfig;

Expand Down Expand Up @@ -191,7 +198,8 @@ private ExportOptions createExportOptions(Properties parameters) {
.setExtensions(Parameter.readStringList(getFormat(), parameters, EXTENSIONS_LIST_PARAMETER, defaultValueConfig) != null ? new HashSet<>(Parameter.readStringList(getFormat(), parameters, EXTENSIONS_LIST_PARAMETER, defaultValueConfig)) : null)
.setSorted(Parameter.readBoolean(getFormat(), parameters, SORTED_PARAMETER, defaultValueConfig))
.setVersion(Parameter.readString(getFormat(), parameters, VERSION_PARAMETER, defaultValueConfig))
.setFormat(getTreeDataFormat());
.setFormat(getTreeDataFormat())
.setWithAutomationSystems(Parameter.readBoolean(getFormat(), parameters, WITH_AUTOMATION_SYSTEMS_PARAMETER, defaultValueConfig));
addExtensionsVersions(parameters, options);
return options;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public enum IidmVersionIncompatibilityBehavior {
*/
private boolean sorted = false;

private boolean withAutomationSystems = true;

public ExportOptions() {
}

Expand Down Expand Up @@ -233,4 +235,13 @@ public ExportOptions setSorted(boolean sorted) {
this.sorted = sorted;
return this;
}

public boolean isWithAutomationSystems() {
return withAutomationSystems;
}

public ExportOptions setWithAutomationSystems(boolean withAutomationSystems) {
this.withAutomationSystems = withAutomationSystems;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ private static void writeThreeWindingsTransformers(Substation s, NetworkSerializ
}

private static void writeOverloadManagementSystems(Substation s, NetworkSerializerContext context) {
if (!context.getOptions().isWithAutomationSystems()) {
return;
}
IidmSerDeUtil.runFromMinimumVersion(IidmVersion.V_1_12, context, () -> {
context.getWriter().writeStartNodes();
IidmSerDeUtil.sorted(s.getOverloadManagementSystems(), context.getOptions())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@ protected void testForAllPreviousVersions(IidmVersion maxVersion, Consumer<IidmV
.forEach(test);
}

/**
* Execute a given test for all IIDM versions newer or equal than a given minimum IIDM version.
*/
protected void testForAllVersionsSince(IidmVersion minVersion, Consumer<IidmVersion> test) {
Stream.of(IidmVersion.values())
.filter(v -> v.compareTo(minVersion) >= 0)
.forEach(test);
}

/**
* Execute a write test for the given network, for all IIDM versions strictly older than a given maximum IIDM
* version, and compare to the given versioned xml reference test resource.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ void exportOptionsTest2() {
ExportOptions options = new ExportOptions();
options.setCharset(StandardCharsets.ISO_8859_1);
options.setExtensions(extensionsList);
options.setWithAutomationSystems(false);
assertEquals(0, (int) options.getExtensions().map(Set::size).orElse(-1));
assertEquals(StandardCharsets.ISO_8859_1, options.getCharset());
assertFalse(options.isWithAutomationSystems());
}

@Test
Expand Down Expand Up @@ -85,5 +87,6 @@ private void testDefaultExportOptions(ExportOptions options) {
assertEquals(IidmSerDeConstants.CURRENT_IIDM_VERSION, options.getVersion());
assertEquals(THROW_EXCEPTION, options.getIidmVersionIncompatibilityBehavior());
assertEquals(StandardCharsets.UTF_8, options.getCharset());
assertEquals(Boolean.TRUE, options.isWithAutomationSystems());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,21 @@
*/
package com.powsybl.iidm.serde;

import com.powsybl.commons.io.TreeDataFormat;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.serde.anonymizer.Anonymizer;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.io.IOException;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.time.ZonedDateTime;
import java.util.stream.Stream;

import static com.powsybl.iidm.serde.IidmSerDeConstants.CURRENT_IIDM_VERSION;

Expand All @@ -20,16 +30,85 @@
*/
class OverloadManagementSystemSerDeTest extends AbstractIidmSerDeTest {

private static Network network;

@BeforeAll
public static void setup() {
network = createNetwork();
}

@Test
void roundTripTest() throws IOException {
Network network = createNetwork();

// backward compatibility
allFormatsRoundTripAllPreviousVersionedXmlTest("overloadManagementSystemRoundTripRef.xml");
allFormatsRoundTripTest(network, "overloadManagementSystemRoundTripRef.xml", CURRENT_IIDM_VERSION);
}

private Network createNetwork() {
private record ExportResult(Anonymizer anonymizer, String content) {
}

static Stream<Arguments> provideFormats() {
return Stream.of(
Arguments.of(TreeDataFormat.JSON),
Arguments.of(TreeDataFormat.XML)
);
}

@ParameterizedTest
@MethodSource("provideFormats")
void exportDisabledTest(TreeDataFormat format) {
testForAllVersionsSince(IidmVersion.V_1_12, v -> exportDisabledTest(format, v));
}

private void exportDisabledTest(TreeDataFormat format, IidmVersion version) {
// Export the network without the automation systems
ExportResult exportResult = writeNetwork(format, version);
// Check that the exported String does NOT contain OMS tags
Assertions.assertFalse(exportResult.content().contains(OverloadManagementSystemSerDe.ROOT_ELEMENT_NAME));
// Load the exported String to check if it is really valid
Network networkOutput = readNetwork(format, exportResult);
// Check that the read network has substations, lines, ... but no OMS (none were exported)
checkNetworkAgainstRef(networkOutput, false);
}

private static ExportResult writeNetwork(TreeDataFormat format, IidmVersion version) {
ExportOptions options = new ExportOptions()
.setFormat(format)
.setWithAutomationSystems(false)
.setVersion(version.toString("."));
ExportResult exportResult;
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
Anonymizer anonymizer = NetworkSerDe.write(network, options, os);
String exportedContent = os.toString(StandardCharsets.UTF_8);
exportResult = new ExportResult(anonymizer, exportedContent);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
return exportResult;
}

private static Network readNetwork(TreeDataFormat format, ExportResult exportResult) {
ImportOptions options = new ImportOptions()
.setFormat(format);
Network networkOutput;
try (InputStream is = IOUtils.toInputStream(exportResult.content(), "UTF-8")) {
networkOutput = NetworkSerDe.read(is, options, exportResult.anonymizer());
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
return networkOutput;
}

private static void checkNetworkAgainstRef(Network networkOutput, boolean shouldHaveAutomationSystems) {
Assertions.assertEquals(network.getSubstationCount(), networkOutput.getSubstationCount());
Assertions.assertEquals(network.getLineCount(), networkOutput.getLineCount());
Assertions.assertEquals(network.getTwoWindingsTransformerCount(), networkOutput.getTwoWindingsTransformerCount());
Assertions.assertEquals(network.getThreeWindingsTransformerCount(), networkOutput.getThreeWindingsTransformerCount());
int expectedNbAutomationSystem = shouldHaveAutomationSystems ? network.getOverloadManagementSystemCount() : 0;
Assertions.assertEquals(expectedNbAutomationSystem, networkOutput.getOverloadManagementSystemCount());
}

private static Network createNetwork() {
Network network = NetworkFactory.findDefault().createNetwork("fictitious", "test");
network.setCaseDate(ZonedDateTime.parse("2024-01-02T15:00:00.000+01:00"));
network.setForecastDistance(0);
Expand Down Expand Up @@ -109,7 +188,7 @@ private Network createNetwork() {
return network;
}

private VoltageLevel createVoltageLevel(Substation substation, int nominalV) {
private static VoltageLevel createVoltageLevel(Substation substation, int nominalV) {
String vlId = String.format("%s_%d", substation.getId(), nominalV);
VoltageLevel vl = substation.newVoltageLevel()
.setId(vlId)
Expand All @@ -123,7 +202,7 @@ private VoltageLevel createVoltageLevel(Substation substation, int nominalV) {
return vl;
}

private void createLine(Network network, VoltageLevel s1v400, VoltageLevel s2v400, int nb) {
private static void createLine(Network network, VoltageLevel s1v400, VoltageLevel s2v400, int nb) {
createSwitch(s1v400, "S1_400_LINE_" + nb + "_DISCONNECTOR", SwitchKind.DISCONNECTOR, 0, nb);
createSwitch(s1v400, "S1_400_LINE_" + nb + "_BREAKER", SwitchKind.BREAKER, nb, 10 + nb);
createSwitch(s2v400, "S2_400_LINE_" + nb + "_DISCONNECTOR", SwitchKind.DISCONNECTOR, 0, nb);
Expand All @@ -143,7 +222,7 @@ private void createLine(Network network, VoltageLevel s1v400, VoltageLevel s2v40
.add();
}

private void createTwoWindingsTransformer(Substation s1, VoltageLevel s1v400, VoltageLevel s1v225) {
private static void createTwoWindingsTransformer(Substation s1, VoltageLevel s1v400, VoltageLevel s1v225) {
createSwitch(s1v400, "S1_400_BBS_2WT_DISCONNECTOR", SwitchKind.DISCONNECTOR, 0, 13);
createSwitch(s1v400, "S1_400_2WT_BREAKER", SwitchKind.BREAKER, 13, 23);
createSwitch(s1v225, "S1_225_BBS_2WT_DISCONNECTOR", SwitchKind.DISCONNECTOR, 0, 13);
Expand All @@ -163,7 +242,7 @@ private void createTwoWindingsTransformer(Substation s1, VoltageLevel s1v400, Vo
.add();
}

private void createThreeWindingsTransformer(Substation s1, VoltageLevel s1v400, VoltageLevel s1v225, VoltageLevel s1v90) {
private static void createThreeWindingsTransformer(Substation s1, VoltageLevel s1v400, VoltageLevel s1v225, VoltageLevel s1v90) {
createSwitch(s1v400, "S1_400_BBS_3WT_DISCONNECTOR", SwitchKind.DISCONNECTOR, 0, 14);
createSwitch(s1v400, "S1_400_3WT_BREAKER", SwitchKind.BREAKER, 14, 24);
createSwitch(s1v225, "S1_225_BBS_3WT_DISCONNECTOR", SwitchKind.DISCONNECTOR, 0, 14);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void exportTest() throws IOException {
@Test
void paramsTest() {
var xmlExporter = new XMLExporter();
assertEquals(10, xmlExporter.getParameters().size());
assertEquals(11, xmlExporter.getParameters().size());
assertEquals("IIDM XML v" + CURRENT_IIDM_VERSION.toString(".") + " exporter", xmlExporter.getComment());
}

Expand Down

0 comments on commit 86ec61f

Please sign in to comment.