Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ protected boolean isValid(T identifiable, P parent) {

protected abstract void writeRootElementAttributes(T identifiable, P parent, NetworkSerializerContext context);

protected void addExtinctExtensions(T identifiable, NetworkSerializerContext context) {
}

protected void writeSubElements(T identifiable, P parent, NetworkSerializerContext context) {
}

Expand All @@ -38,6 +41,7 @@ public final void write(T identifiable, P parent, NetworkSerializerContext conte
IidmSerDeUtil.runFromMinimumVersion(IidmVersion.V_1_2, context, () -> context.getWriter().writeBooleanAttribute("fictitious", identifiable.isFictitious(), false));

writeRootElementAttributes(identifiable, parent, context);
addExtinctExtensions(identifiable, context);

IidmSerDeUtil.runFromMinimumVersion(IidmVersion.V_1_3, context, () -> AliasesSerDe.write(identifiable, getRootElementName(), context));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import com.powsybl.iidm.network.Battery;
import com.powsybl.iidm.network.BatteryAdder;
import com.powsybl.iidm.network.VoltageLevel;
import com.powsybl.iidm.network.extensions.removed.VoltageRegulationExtension;
import com.powsybl.iidm.network.regulation.RegulationMode;
import com.powsybl.iidm.serde.util.IidmSerDeUtil;

import static com.powsybl.iidm.serde.ConnectableSerDeUtil.*;
Expand Down Expand Up @@ -43,6 +45,17 @@ protected void writeRootElementAttributes(Battery b, VoltageLevel vl, NetworkSer
writePQ(null, b.getTerminal(), context.getWriter());
}

@Override
protected void addExtinctExtensions(Battery b, NetworkSerializerContext context) {
if (com.powsybl.iidm.serde.extensions.VoltageRegulationSerDe.isExtensionNeededAndExportable(b, context)) {
VoltageRegulationExtension extension = new VoltageRegulationExtension(b,
b.getVoltageRegulation().getTerminal(),
b.getVoltageRegulation().getMode() == RegulationMode.VOLTAGE,
b.getVoltageRegulation().getTargetValue());
context.addExtinctExtensionsToSerialize(b.getId(), extension);
}
}

@Override
protected void writeSubElements(Battery b, VoltageLevel vl, NetworkSerializerContext context) {
ReactiveLimitsSerDe.INSTANCE.write(b, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
package com.powsybl.iidm.serde;

import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.removed.RemoteReactivePowerControl;
import com.powsybl.iidm.network.regulation.RegulationMode;
import com.powsybl.iidm.serde.extensions.RemoteReactivePowerControlSerDe;
import com.powsybl.iidm.serde.util.IidmSerDeUtil;

import java.util.concurrent.atomic.AtomicReference;
Expand Down Expand Up @@ -90,6 +92,17 @@ private static void writeTargetQByVersion(Generator g, NetworkSerializerContext
context.getWriter().writeDoubleAttribute("targetQ", g.getTargetQ()));
}

@Override
protected void addExtinctExtensions(Generator g, NetworkSerializerContext context) {
if (RemoteReactivePowerControlSerDe.isExtensionNeededAndExportable(g, context)) {
RemoteReactivePowerControl extension = new RemoteReactivePowerControl(g,
g.getVoltageRegulation().getTargetValue(),
g.getVoltageRegulation().getTerminal(),
g.getVoltageRegulation().isRegulating());
context.addExtinctExtensionsToSerialize(g.getId(), extension);
}
}

@Override
protected void writeSubElements(Generator g, VoltageLevel vl, NetworkSerializerContext context) {
IidmSerDeUtil.runUntilMaximumVersion(IidmVersion.V_1_15, context, () -> {
Expand Down
224 changes: 90 additions & 134 deletions iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/NetworkSerDe.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
*/
package com.powsybl.iidm.serde;

import com.powsybl.commons.extensions.Extension;
import com.powsybl.commons.io.SerializerContext;
import com.powsybl.commons.io.TreeDataWriter;
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.TopologyLevel;
import com.powsybl.iidm.serde.anonymizer.Anonymizer;

import java.util.*;
import java.util.stream.Stream;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
Expand All @@ -26,6 +28,7 @@ public class NetworkSerializerContext extends AbstractNetworkSerDeContext<Export
private final boolean valid;
private final Set<Identifiable> exportedEquipments;
private final Map<String, TopologyLevel> voltageLevelExportTopologyLevel;
private final Map<String, List<Extension<? extends Identifiable<?>>>> extinctExtensionsToSerializeByIdentifiable;

NetworkSerializerContext(Anonymizer anonymizer, TreeDataWriter writer, ExportOptions options, BusFilter filter, IidmVersion version, boolean valid) {
super(anonymizer, version);
Expand All @@ -35,6 +38,7 @@ public class NetworkSerializerContext extends AbstractNetworkSerDeContext<Export
this.valid = valid;
this.exportedEquipments = new HashSet<>();
this.voltageLevelExportTopologyLevel = new HashMap<>();
this.extinctExtensionsToSerializeByIdentifiable = new HashMap<>();
}

@Override
Expand Down Expand Up @@ -84,4 +88,14 @@ public void addVoltageLevelExportTopologyLevel(String voltageLevelId, TopologyLe
public TopologyLevel getVoltageLevelExportTopologyLevel(String voltageLevelId) {
return voltageLevelExportTopologyLevel.get(voltageLevelId);
}

public void addExtinctExtensionsToSerialize(String identifiableId, Extension<? extends Identifiable<?>> extension) {
extinctExtensionsToSerializeByIdentifiable.computeIfAbsent(identifiableId, k -> new ArrayList<>()).add(extension);
}

public Stream<Extension<Identifiable<?>>> getExtinctExtensionsToSerialize(String identifiableId) {
return extinctExtensionsToSerializeByIdentifiable.containsKey(identifiableId) ?
extinctExtensionsToSerializeByIdentifiable.get(identifiableId).stream()
.map(e -> (Extension<Identifiable<?>>) e) : Stream.empty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2026, 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.iidm.serde.extensions;

import com.powsybl.commons.extensions.Extendable;
import com.powsybl.commons.extensions.Extension;
import com.powsybl.commons.extensions.ExtensionSerDe;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.serde.ExportOptions;
import com.powsybl.iidm.serde.IidmVersion;

/**
* <p>Interface for the (de)serialization of extensions that no longer exists.</p>
* <p>It is useful for backward compatibility purposes.</p>
*
* @author Olivier Perrin {@literal <olivier.perrin at rte-france.com>}
*/
public interface ExtinctExtensionSerDe<T extends Extendable, E extends Extension<T>> extends ExtensionSerDe<T, E> {

default boolean isExtensionNeededAndExportable(Network network, ExportOptions options) {
return isExtensionExportable(options) && isExtensionNeeded(network);
}

private boolean isExtensionExportable(ExportOptions options) {
return isExtensionExportable(options, getName(), getLastSupportedVersion());
}

static boolean isExtensionExportable(ExportOptions options, String extensionName, IidmVersion lastSupportedVersion) {
return options.withExtension(extensionName) && options.getVersion().compareTo(lastSupportedVersion) <= 0;
}

IidmVersion getLastSupportedVersion();

boolean isExtensionNeeded(Network network);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2026, 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.iidm.serde.extensions;

import com.powsybl.commons.util.ServiceLoaderCache;

import java.util.List;

/**
* @author Olivier Perrin {@literal <olivier.perrin at rte-france.com>}
*/
public final class ExtinctExtensionSerDeService {

private static final ServiceLoaderCache<ExtinctExtensionSerDe> EXTINCT_SERDE_SERVICE = new ServiceLoaderCache<>(ExtinctExtensionSerDe.class);

private ExtinctExtensionSerDeService() {
}

public static List<ExtinctExtensionSerDe> findAll() {
return EXTINCT_SERDE_SERVICE.getServices();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.powsybl.commons.io.DeserializerContext;
import com.powsybl.commons.io.SerializerContext;
import com.powsybl.iidm.network.Generator;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.Terminal;
import com.powsybl.iidm.network.extensions.removed.RemoteReactivePowerControl;
import com.powsybl.iidm.network.regulation.RegulationMode;
Expand All @@ -25,8 +26,11 @@
/**
* @author Damien Jeandemange {@literal <damien.jeandemange at artelys.com>}
*/
@AutoService(ExtensionSerDe.class)
public class RemoteReactivePowerControlSerDe extends AbstractExtensionSerDe<Generator, RemoteReactivePowerControl> {
@AutoService({ExtensionSerDe.class, ExtinctExtensionSerDe.class})
public class RemoteReactivePowerControlSerDe extends AbstractExtensionSerDe<Generator, RemoteReactivePowerControl>
implements ExtinctExtensionSerDe<Generator, RemoteReactivePowerControl> {

public static final IidmVersion LAST_SUPPORTED_VERSION = IidmVersion.V_1_15;

public RemoteReactivePowerControlSerDe() {
super(RemoteReactivePowerControl.NAME, "network", RemoteReactivePowerControl.class,
Expand Down Expand Up @@ -62,4 +66,25 @@ public RemoteReactivePowerControl read(Generator extendable, DeserializerContext
}
return null;
}

@Override
public IidmVersion getLastSupportedVersion() {
return LAST_SUPPORTED_VERSION;
}

@Override
public boolean isExtensionNeeded(Network n) {
return n.getGeneratorStream().anyMatch(RemoteReactivePowerControlSerDe::isExtensionNeeded);
}

private static boolean isExtensionNeeded(Generator g) {
return g.getVoltageRegulation() != null
&& g.getVoltageRegulation().getTerminal() != null
&& g.getVoltageRegulation().getMode() == RegulationMode.REACTIVE_POWER;
}

public static boolean isExtensionNeededAndExportable(Generator g, NetworkSerializerContext context) {
return ExtinctExtensionSerDe.isExtensionExportable(context.getOptions(), RemoteReactivePowerControl.NAME, LAST_SUPPORTED_VERSION)
&& isExtensionNeeded(g);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.powsybl.commons.io.DeserializerContext;
import com.powsybl.commons.io.SerializerContext;
import com.powsybl.iidm.network.Battery;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.extensions.removed.VoltageRegulationExtension;
import com.powsybl.iidm.network.regulation.RegulationMode;
import com.powsybl.iidm.network.regulation.VoltageRegulation;
Expand All @@ -24,8 +25,11 @@
/**
* @author Coline Piloquet {@literal <coline.piloquet@rte-france.fr>}
*/
@AutoService(ExtensionSerDe.class)
public class VoltageRegulationSerDe extends AbstractVersionableNetworkExtensionSerDe<Battery, VoltageRegulationExtension, VoltageRegulationSerDe.Version> {
@AutoService({ExtensionSerDe.class, ExtinctExtensionSerDe.class})
public class VoltageRegulationSerDe extends AbstractVersionableNetworkExtensionSerDe<Battery, VoltageRegulationExtension, VoltageRegulationSerDe.Version>
implements ExtinctExtensionSerDe<Battery, VoltageRegulationExtension> {

public static final IidmVersion LAST_SUPPORTED_VERSION = IidmVersion.V_1_15;

public enum Version implements SerDeVersion<Version> {
V_1_0_LEGACY("/xsd/voltageRegulation_V1_0_legacy.xsd", "http://www.itesla_project.eu/schema/iidm/ext/voltageregulation/1_0",
Expand Down Expand Up @@ -117,4 +121,23 @@ protected Version getDefaultVersion() {
// Default version is v1.1, the subsequent ones have been added without any change
return Version.V_1_1;
}

@Override
public IidmVersion getLastSupportedVersion() {
return LAST_SUPPORTED_VERSION;
}

@Override
public boolean isExtensionNeeded(Network n) {
return n.getBatteryStream().anyMatch(VoltageRegulationSerDe::isExtensionNeeded);
}

private static boolean isExtensionNeeded(Battery b) {
return b.getVoltageRegulation() != null;
}

public static boolean isExtensionNeededAndExportable(Battery b, NetworkSerializerContext context) {
return ExtinctExtensionSerDe.isExtensionExportable(context.getOptions(), VoltageRegulationExtension.NAME, LAST_SUPPORTED_VERSION)
&& isExtensionNeeded(b);
}
}