From 64a09eb92bae2938aac12620a279d1d88d31217b Mon Sep 17 00:00:00 2001 From: "VIDAL Didier (Externe)" Date: Mon, 3 Jun 2024 14:56:47 +0200 Subject: [PATCH 1/7] Add the ability to override minP and maxP to reflect generator temporary limits Signed-off-by: VIDAL Didier (Externe) --- .../extensions/ActivePowerControl.java | 23 +++++ .../extensions/ActivePowerControlAdder.java | 4 + .../ActivePowerControlAdderImpl.java | 16 +++- .../extensions/ActivePowerControlImpl.java | 50 ++++++++++- .../AbstractActivePowerControlTest.java | 90 +++++++++++++++++++ 5 files changed, 180 insertions(+), 3 deletions(-) diff --git a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java index 0dd18ffb477..da5bfe59c87 100644 --- a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java +++ b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java @@ -10,6 +10,8 @@ import com.powsybl.commons.extensions.Extension; import com.powsybl.iidm.network.Injection; +import java.util.Optional; + /** * @author Ghiles Abdellah {@literal } */ @@ -54,4 +56,25 @@ default String getName() { */ void setParticipationFactor(double participationFactor); + /** + * @return if present, provides the overridden value of pmin to be used for active power control operations. + */ + Optional getMinPOverride(); + + /** + * Sets the overridden minimal active power. + * @param pMinOverride The overridden value of Pmin. A Null or Nan value removes the override. + */ + void setMinPOverride(Double pMinOverride); + + /** + * @return if present, provides the overridden value of pmax to be used for active power control operations. + */ + Optional getMaxPOverride(); + + /** + * Sets the overridden maximal active power. + * @param pMaxOverride The overridden value of Pmax. A Null or Nan value removes the override. + */ + void setMaxPOverride(Double pMaxOverride); } diff --git a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControlAdder.java b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControlAdder.java index 22f64c6200f..ad333b70a0d 100644 --- a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControlAdder.java +++ b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControlAdder.java @@ -23,4 +23,8 @@ default Class getExtensionClass() { ActivePowerControlAdder withDroop(double droop); ActivePowerControlAdder withParticipationFactor(double participationFactor); + + ActivePowerControlAdder withMinPOverridde(double minPOverridde); + + ActivePowerControlAdder withMaxPOverride(double maxPOverride); } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlAdderImpl.java index e0fae2e5f70..4332d23b780 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlAdderImpl.java @@ -20,6 +20,8 @@ public class ActivePowerControlAdderImpl> private double droop = Double.NaN; private double participationFactor = Double.NaN; + private double minPOverride = Double.NaN; + private double maxPOverride = Double.NaN; protected ActivePowerControlAdderImpl(I extendable) { super(extendable); @@ -27,7 +29,7 @@ protected ActivePowerControlAdderImpl(I extendable) { @Override protected ActivePowerControlImpl createExtension(I extendable) { - return new ActivePowerControlImpl<>(extendable, participate, droop, participationFactor); + return new ActivePowerControlImpl<>(extendable, participate, droop, participationFactor, minPOverride, maxPOverride); } @Override @@ -48,4 +50,16 @@ public ActivePowerControlAdder withParticipationFactor(double participationFa return this; } + @Override + public ActivePowerControlAdder withMinPOverridde(double minPOverridde) { + this.minPOverride = minPOverridde; + return this; + } + + @Override + public ActivePowerControlAdder withMaxPOverride(double maxPOverride) { + this.maxPOverride = maxPOverride; + return this; + } + } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java index cd085d0b9dc..a558fe4d148 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java @@ -14,6 +14,7 @@ import gnu.trove.list.array.TDoubleArrayList; import java.util.List; +import java.util.Optional; /** * @author Ghiles Abdellah {@literal } @@ -26,22 +27,38 @@ public class ActivePowerControlImpl> extends AbstractMult private final TDoubleArrayList droop; private final TDoubleArrayList participationFactor; + private final TDoubleArrayList minPOverride; + private final TDoubleArrayList maxPOverride; + private final List allTDoubleArrayLists; public ActivePowerControlImpl(T component, boolean participate, double droop, double participationFactor) { + this(component, participate, droop, participationFactor, Double.NaN, Double.NaN); + } + + public ActivePowerControlImpl(T component, + boolean participate, + double droop, + double participationFactor, + double minPOverride, + double maxPOverride) { super(component); int variantArraySize = getVariantManagerHolder().getVariantManager().getVariantArraySize(); this.participate = new TBooleanArrayList(variantArraySize); this.droop = new TDoubleArrayList(variantArraySize); this.participationFactor = new TDoubleArrayList(variantArraySize); - this.allTDoubleArrayLists = List.of(this.droop, this.participationFactor); + this.minPOverride = new TDoubleArrayList(variantArraySize); + this.maxPOverride = new TDoubleArrayList(variantArraySize); + this.allTDoubleArrayLists = List.of(this.droop, this.participationFactor, this.minPOverride, this.maxPOverride); for (int i = 0; i < variantArraySize; i++) { this.participate.add(participate); this.droop.add(droop); this.participationFactor.add(participationFactor); + this.minPOverride.add(minPOverride); + this.maxPOverride.add(maxPOverride); } } @@ -94,8 +111,37 @@ public void deleteVariantArrayElement(int index) { public void allocateVariantArrayElement(int[] indexes, int sourceIndex) { for (int index : indexes) { participate.set(index, participate.get(sourceIndex)); - droop.set(index, droop.get(sourceIndex)); allTDoubleArrayLists.forEach(dl -> dl.set(index, dl.get(sourceIndex))); } } + + @Override + public Optional getMinPOverride() { + double result = minPOverride.get(getVariantIndex()); + return Double.isNaN(result) ? Optional.empty() : Optional.of(result); + } + + @Override + public void setMinPOverride(Double minPOverride) { + if (minPOverride == null) { + this.minPOverride.set(getVariantIndex(), Double.NaN); + } else { + this.minPOverride.set(getVariantIndex(), minPOverride); + } + } + + @Override + public Optional getMaxPOverride() { + double result = maxPOverride.get(getVariantIndex()); + return Double.isNaN(result) ? Optional.empty() : Optional.of(result); + } + + @Override + public void setMaxPOverride(Double maxPOverride) { + if (maxPOverride == null) { + this.maxPOverride.set(getVariantIndex(), Double.NaN); + } else { + this.maxPOverride.set(getVariantIndex(), maxPOverride); + } + } } diff --git a/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java b/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java index d5b3e28ae5a..40ee1d0bb4d 100644 --- a/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java +++ b/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java @@ -100,15 +100,105 @@ public void variantsCloneTest() { } } + @Test + public void variantsCloneTestWithOverride() { + String variant1 = "variant1"; + String variant2 = "variant2"; + String variant3 = "variant3"; + + Network network = BatteryNetworkFactory.create(); + Battery bat = network.getBattery("BAT"); + assertNotNull(bat); + bat.newExtension(ActivePowerControlAdder.class) + .withDroop(4.0) + .withParticipate(true) + .withParticipationFactor(1.2) + .withMinPOverridde(10) + .withMaxPOverride(100) + .add(); + ActivePowerControl activePowerControl = bat.getExtension(ActivePowerControl.class); + assertNotNull(activePowerControl); + + // Testing variant cloning + VariantManager variantManager = network.getVariantManager(); + variantManager.cloneVariant(INITIAL_VARIANT_ID, variant1); + variantManager.cloneVariant(variant1, variant2); + variantManager.setWorkingVariant(variant1); + checkValues3(activePowerControl); + + // Testing setting different values in the cloned variant and going back to the initial one + activePowerControl.setDroop(6.0); + activePowerControl.setParticipate(false); + activePowerControl.setParticipationFactor(3.0); + activePowerControl.setMaxPOverride(110.); + activePowerControl.setMinPOverride(null); + checkValues4(activePowerControl); + activePowerControl.setMinPOverride(Double.NaN); + checkValues4(activePowerControl); + + activePowerControl.setMinPOverride(11.); + activePowerControl.setMaxPOverride(null); + checkValues5(activePowerControl); + + variantManager.setWorkingVariant(INITIAL_VARIANT_ID); + checkValues3(activePowerControl); + + // Removes a variant then adds another variant to test variant recycling (hence calling allocateVariantArrayElement) + variantManager.removeVariant(variant1); + List targetVariantIds = Arrays.asList(variant1, variant3); + variantManager.cloneVariant(INITIAL_VARIANT_ID, targetVariantIds); + variantManager.setWorkingVariant(variant1); + checkValues3(activePowerControl); + variantManager.setWorkingVariant(variant3); + checkValues3(activePowerControl); + + // Test removing current variant + variantManager.removeVariant(variant3); + try { + activePowerControl.getDroop(); + fail(); + } catch (PowsyblException e) { + assertEquals("Variant index not set", e.getMessage()); + } + } + private static void checkValues1(ActivePowerControl activePowerControl) { assertTrue(activePowerControl.isParticipate()); assertEquals(4.0, activePowerControl.getDroop(), 0.0); assertEquals(1.2, activePowerControl.getParticipationFactor(), 0.0); + assertTrue(activePowerControl.getMaxPOverride().isEmpty()); + assertTrue(activePowerControl.getMinPOverride().isEmpty()); } private static void checkValues2(ActivePowerControl activePowerControl) { assertFalse(activePowerControl.isParticipate()); assertEquals(6.0, activePowerControl.getDroop(), 0.0); assertEquals(3.0, activePowerControl.getParticipationFactor(), 0.0); + assertTrue(activePowerControl.getMaxPOverride().isEmpty()); + assertTrue(activePowerControl.getMinPOverride().isEmpty()); + } + + private static void checkValues3(ActivePowerControl activePowerControl) { + assertTrue(activePowerControl.isParticipate()); + assertEquals(4.0, activePowerControl.getDroop(), 0.0); + assertEquals(1.2, activePowerControl.getParticipationFactor(), 0.0); + assertEquals(10, activePowerControl.getMinPOverride().get()); + assertEquals(100, activePowerControl.getMaxPOverride().get()); + } + + private static void checkValues4(ActivePowerControl activePowerControl) { + assertFalse(activePowerControl.isParticipate()); + assertEquals(6.0, activePowerControl.getDroop(), 0.0); + assertEquals(3.0, activePowerControl.getParticipationFactor(), 0.0); + assertTrue(activePowerControl.getMinPOverride().isEmpty()); + assertEquals(110, activePowerControl.getMaxPOverride().get()); + } + + private static void checkValues5(ActivePowerControl activePowerControl) { + assertFalse(activePowerControl.isParticipate()); + assertEquals(6.0, activePowerControl.getDroop(), 0.0); + assertEquals(3.0, activePowerControl.getParticipationFactor(), 0.0); + assertTrue(activePowerControl.getMaxPOverride().isEmpty()); + assertEquals(11, activePowerControl.getMinPOverride().get()); } } From d40cd5e732215157bb20ec06fcd357518dacea41 Mon Sep 17 00:00:00 2001 From: "VIDAL Didier (Externe)" Date: Mon, 3 Jun 2024 17:26:38 +0200 Subject: [PATCH 2/7] Serialization of new optional attributes Signed-off-by: VIDAL Didier (Externe) --- .../extensions/ActivePowerControl.java | 8 ++-- .../extensions/ActivePowerControlAdder.java | 2 +- .../ActivePowerControlAdderImpl.java | 4 +- .../extensions/ActivePowerControlImpl.java | 16 ++------ .../extensions/ActivePowerControlSerDe.java | 20 ++++++++-- .../resources/xsd/activePowerControl_V1_2.xsd | 24 ++++++++++++ .../extensions/ActivePowerControlXmlTest.java | 29 +++++++++++++- ...ctivePowerControlWithLimitRoundTripRef.xml | 38 +++++++++++++++++++ .../eurostag-tutorial1-lf-extensions.json | 2 +- .../AbstractActivePowerControlTest.java | 6 +-- 10 files changed, 120 insertions(+), 29 deletions(-) create mode 100644 iidm/iidm-serde/src/main/resources/xsd/activePowerControl_V1_2.xsd create mode 100644 iidm/iidm-serde/src/test/resources/V1_12/activePowerControlWithLimitRoundTripRef.xml diff --git a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java index da5bfe59c87..b1be4c77a4b 100644 --- a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java +++ b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java @@ -63,9 +63,9 @@ default String getName() { /** * Sets the overridden minimal active power. - * @param pMinOverride The overridden value of Pmin. A Null or Nan value removes the override. + * @param pMinOverride The overridden value of Pmin. A Nan value removes the override. */ - void setMinPOverride(Double pMinOverride); + void setMinPOverride(double pMinOverride); /** * @return if present, provides the overridden value of pmax to be used for active power control operations. @@ -74,7 +74,7 @@ default String getName() { /** * Sets the overridden maximal active power. - * @param pMaxOverride The overridden value of Pmax. A Null or Nan value removes the override. + * @param pMaxOverride The overridden value of Pmax. A Nan value removes the override. */ - void setMaxPOverride(Double pMaxOverride); + void setMaxPOverride(double pMaxOverride); } diff --git a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControlAdder.java b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControlAdder.java index ad333b70a0d..b4d6e500b2f 100644 --- a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControlAdder.java +++ b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControlAdder.java @@ -24,7 +24,7 @@ default Class getExtensionClass() { ActivePowerControlAdder withParticipationFactor(double participationFactor); - ActivePowerControlAdder withMinPOverridde(double minPOverridde); + ActivePowerControlAdder withMinPOverride(double minPOverride); ActivePowerControlAdder withMaxPOverride(double maxPOverride); } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlAdderImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlAdderImpl.java index 4332d23b780..69235972c9e 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlAdderImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlAdderImpl.java @@ -51,8 +51,8 @@ public ActivePowerControlAdder withParticipationFactor(double participationFa } @Override - public ActivePowerControlAdder withMinPOverridde(double minPOverridde) { - this.minPOverride = minPOverridde; + public ActivePowerControlAdder withMinPOverride(double minPOverride) { + this.minPOverride = minPOverride; return this; } diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java index a558fe4d148..05acf498c3d 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java @@ -122,12 +122,8 @@ public Optional getMinPOverride() { } @Override - public void setMinPOverride(Double minPOverride) { - if (minPOverride == null) { - this.minPOverride.set(getVariantIndex(), Double.NaN); - } else { - this.minPOverride.set(getVariantIndex(), minPOverride); - } + public void setMinPOverride(double minPOverride) { + this.minPOverride.set(getVariantIndex(), minPOverride); } @Override @@ -137,11 +133,7 @@ public Optional getMaxPOverride() { } @Override - public void setMaxPOverride(Double maxPOverride) { - if (maxPOverride == null) { - this.maxPOverride.set(getVariantIndex(), Double.NaN); - } else { - this.maxPOverride.set(getVariantIndex(), maxPOverride); - } + public void setMaxPOverride(double maxPOverride) { + this.maxPOverride.set(getVariantIndex(), maxPOverride); } } diff --git a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/extensions/ActivePowerControlSerDe.java b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/extensions/ActivePowerControlSerDe.java index d70fad28cee..44eb773c27b 100644 --- a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/extensions/ActivePowerControlSerDe.java +++ b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/extensions/ActivePowerControlSerDe.java @@ -45,11 +45,12 @@ public ActivePowerControlSerDe() { .put(IidmVersion.V_1_9, ImmutableSortedSet.of("1.0", "1.1")) .put(IidmVersion.V_1_10, ImmutableSortedSet.of("1.0", "1.1")) .put(IidmVersion.V_1_11, ImmutableSortedSet.of("1.0", "1.1")) - .put(IidmVersion.V_1_12, ImmutableSortedSet.of("1.0", "1.1")) + .put(IidmVersion.V_1_12, ImmutableSortedSet.of("1.0", "1.1", "1.2")) .build(), new ImmutableMap.Builder() .put("1.0", "http://www.itesla_project.eu/schema/iidm/ext/active_power_control/1_0") .put("1.1", "http://www.powsybl.org/schema/iidm/ext/active_power_control/1_1") + .put("1.2", "http://www.powsybl.org/schema/iidm/ext/active_power_control/1_2") .build()); } @@ -63,16 +64,21 @@ public void write(ActivePowerControl activePowerControl, SerializerContext co if ("1.1".compareTo(extVersionStr) <= 0) { context.getWriter().writeDoubleAttribute("participationFactor", activePowerControl.getParticipationFactor()); } + if ("1.2".compareTo(extVersionStr) <= 0) { + context.getWriter().writeOptionalDoubleAttribute("maxPOverride", activePowerControl.getMaxPOverride().orElse(null)); + context.getWriter().writeOptionalDoubleAttribute("minPOverride", activePowerControl.getMinPOverride().orElse(null)); + } } @Override public InputStream getXsdAsStream() { - return getClass().getResourceAsStream("/xsd/activePowerControl_V1_1.xsd"); + return getClass().getResourceAsStream("/xsd/activePowerControl_V1_2.xsd"); } @Override public List getXsdAsStreamList() { - return List.of(getClass().getResourceAsStream("/xsd/activePowerControl_V1_1.xsd"), + return List.of(getClass().getResourceAsStream("/xsd/activePowerControl_V1_2.xsd"), + getClass().getResourceAsStream("/xsd/activePowerControl_V1_1.xsd"), getClass().getResourceAsStream("/xsd/activePowerControl_V1_0.xsd")); } @@ -81,16 +87,24 @@ public ActivePowerControl read(T identifiable, DeserializerContext context) { boolean participate = context.getReader().readBooleanAttribute("participate"); double droop = context.getReader().readDoubleAttribute("droop"); double participationFactor = Double.NaN; + double minPOverride = Double.NaN; + double maxPOverride = Double.NaN; NetworkDeserializerContext networkContext = (NetworkDeserializerContext) context; String extVersionStr = networkContext.getExtensionVersion(this).orElseThrow(IllegalStateException::new); if ("1.1".compareTo(extVersionStr) <= 0) { participationFactor = context.getReader().readDoubleAttribute("participationFactor"); } + if ("1.2".compareTo(extVersionStr) <= 0) { + maxPOverride = context.getReader().readOptionalDoubleAttribute("maxPOverride").orElse(Double.NaN); + minPOverride = context.getReader().readOptionalDoubleAttribute("minPOverride").orElse(Double.NaN); + } context.getReader().readEndNode(); ActivePowerControlAdder activePowerControlAdder = identifiable.newExtension(ActivePowerControlAdder.class); return activePowerControlAdder.withParticipate(participate) .withDroop(droop) .withParticipationFactor(participationFactor) + .withMinPOverride(minPOverride) + .withMaxPOverride(maxPOverride) .add(); } } diff --git a/iidm/iidm-serde/src/main/resources/xsd/activePowerControl_V1_2.xsd b/iidm/iidm-serde/src/main/resources/xsd/activePowerControl_V1_2.xsd new file mode 100644 index 00000000000..d53fa4a9ca9 --- /dev/null +++ b/iidm/iidm-serde/src/main/resources/xsd/activePowerControl_V1_2.xsd @@ -0,0 +1,24 @@ + + + + + + + + + + + + + diff --git a/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/extensions/ActivePowerControlXmlTest.java b/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/extensions/ActivePowerControlXmlTest.java index 919deb63a95..cd6ec779c41 100644 --- a/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/extensions/ActivePowerControlXmlTest.java +++ b/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/extensions/ActivePowerControlXmlTest.java @@ -21,7 +21,9 @@ import java.io.IOException; import static com.powsybl.iidm.serde.IidmSerDeConstants.CURRENT_IIDM_VERSION; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author Ghiles Abdellah {@literal } @@ -44,13 +46,36 @@ public void setUp() throws IOException { } @Test - void test() throws IOException { - Network network2 = allFormatsRoundTripTest(network, "/activePowerControlRoundTripRef.xml", CURRENT_IIDM_VERSION); + void testPLimitOverride() throws IOException { + network.getGenerator("GEN").getExtension(ActivePowerControl.class).setMaxPOverride(100.); + network.getBattery("BAT").getExtension(ActivePowerControl.class).setMinPOverride(10.); + Network network2 = allFormatsRoundTripTest(network, "/activePowerControlWithLimitRoundTripRef.xml", CURRENT_IIDM_VERSION); + + Generator gen2 = network2.getGenerator("GEN"); + assertNotNull(gen2); + ActivePowerControl activePowerControl1 = gen2.getExtension(ActivePowerControl.class); + assertNotNull(activePowerControl1); + assertEquals(100, activePowerControl1.getMaxPOverride().get()); + assertTrue(activePowerControl1.getMinPOverride().isEmpty()); + + Battery bat2 = network2.getBattery("BAT"); + assertNotNull(bat2); + ActivePowerControl activePowerControl2 = bat2.getExtension(ActivePowerControl.class); + assertNotNull(activePowerControl2); + assertTrue(activePowerControl2.getMaxPOverride().isEmpty()); + assertEquals(10, activePowerControl2.getMinPOverride().get()); + } + + @Test + void testIidmV11() throws IOException { + Network network2 = allFormatsRoundTripTest(network, "/activePowerControlRoundTripRef.xml", IidmVersion.V_1_11); Battery bat2 = network2.getBattery("BAT"); assertNotNull(bat2); ActivePowerControl activePowerControl2 = bat2.getExtension(ActivePowerControl.class); assertNotNull(activePowerControl2); + assertTrue(activePowerControl2.getMaxPOverride().isEmpty()); + assertTrue(activePowerControl2.getMinPOverride().isEmpty()); } @Test diff --git a/iidm/iidm-serde/src/test/resources/V1_12/activePowerControlWithLimitRoundTripRef.xml b/iidm/iidm-serde/src/test/resources/V1_12/activePowerControlWithLimitRoundTripRef.xml new file mode 100644 index 00000000000..469356d8c44 --- /dev/null +++ b/iidm/iidm-serde/src/test/resources/V1_12/activePowerControlWithLimitRoundTripRef.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/iidm/iidm-serde/src/test/resources/V1_12/eurostag-tutorial1-lf-extensions.json b/iidm/iidm-serde/src/test/resources/V1_12/eurostag-tutorial1-lf-extensions.json index e517fec6c07..7fa2484b7ec 100644 --- a/iidm/iidm-serde/src/test/resources/V1_12/eurostag-tutorial1-lf-extensions.json +++ b/iidm/iidm-serde/src/test/resources/V1_12/eurostag-tutorial1-lf-extensions.json @@ -5,7 +5,7 @@ "version" : "1.1" }, { "extensionName" : "activePowerControl", - "version" : "1.1" + "version" : "1.2" } ], "id" : "sim1", "caseDate" : "2013-01-15T18:45:00.000+01:00", diff --git a/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java b/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java index 40ee1d0bb4d..de60ea29cd0 100644 --- a/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java +++ b/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java @@ -113,7 +113,7 @@ public void variantsCloneTestWithOverride() { .withDroop(4.0) .withParticipate(true) .withParticipationFactor(1.2) - .withMinPOverridde(10) + .withMinPOverride(10) .withMaxPOverride(100) .add(); ActivePowerControl activePowerControl = bat.getExtension(ActivePowerControl.class); @@ -131,13 +131,11 @@ public void variantsCloneTestWithOverride() { activePowerControl.setParticipate(false); activePowerControl.setParticipationFactor(3.0); activePowerControl.setMaxPOverride(110.); - activePowerControl.setMinPOverride(null); - checkValues4(activePowerControl); activePowerControl.setMinPOverride(Double.NaN); checkValues4(activePowerControl); activePowerControl.setMinPOverride(11.); - activePowerControl.setMaxPOverride(null); + activePowerControl.setMaxPOverride(Double.NaN); checkValues5(activePowerControl); variantManager.setWorkingVariant(INITIAL_VARIANT_ID); From 7b461e99402946a2a985e640b710446aa25e0c69 Mon Sep 17 00:00:00 2001 From: "VIDAL Didier (Externe)" Date: Mon, 3 Jun 2024 17:27:25 +0200 Subject: [PATCH 3/7] Remove unncessary and hard to maintain binary test Signed-off-by: VIDAL Didier (Externe) --- .../iidm/serde/EurostagBinaryTest.java | 19 ------------------ .../eurostag-tutorial1-lf-extensions.bin | Bin 1743 -> 0 bytes 2 files changed, 19 deletions(-) delete mode 100644 iidm/iidm-serde/src/test/resources/V1_12/eurostag-tutorial1-lf-extensions.bin diff --git a/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/EurostagBinaryTest.java b/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/EurostagBinaryTest.java index 6e24236fe07..3206071a35b 100644 --- a/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/EurostagBinaryTest.java +++ b/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/EurostagBinaryTest.java @@ -10,9 +10,6 @@ import com.powsybl.commons.io.TreeDataFormat; import com.powsybl.commons.test.ComparisonUtils; import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.extensions.ActivePowerControlAdder; -import com.powsybl.iidm.network.extensions.ConnectablePosition; -import com.powsybl.iidm.network.extensions.ConnectablePositionAdder; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; import org.junit.jupiter.api.Test; @@ -47,20 +44,4 @@ void roundTripTest() throws IOException { roundTripVersionedJsonFromMinToCurrentVersionTest(fileName, IidmVersion.V_1_12); } - @Test - void roundTripTestWithExtension() throws IOException { - ExportOptions exportOptions = new ExportOptions().setFormat(TreeDataFormat.BIN); - ImportOptions importOptions = new ImportOptions().setFormat(TreeDataFormat.BIN); - Network network = EurostagTutorialExample1Factory.createWithLFResults(); - network.getGeneratorStream().findFirst().ifPresent(g -> g.newExtension(ActivePowerControlAdder.class).withDroop(2).withParticipate(true).add()); - network.getLoadStream().forEach(l -> l.newExtension(ConnectablePositionAdder.class).newFeeder().withDirection(ConnectablePosition.Direction.BOTTOM).add().add()); - roundTripTest(network, - (n, binFile) -> NetworkSerDe.write(n, exportOptions, binFile), - binFile -> NetworkSerDe.read(binFile, importOptions), - ComparisonUtils::assertBytesEquals, - getVersionedNetworkPath("eurostag-tutorial1-lf-extensions.bin", CURRENT_IIDM_VERSION)); - - //backward compatibility - roundTripVersionedJsonFromMinToCurrentVersionTest("eurostag-tutorial1-lf-extensions.bin", IidmVersion.V_1_12); - } } diff --git a/iidm/iidm-serde/src/test/resources/V1_12/eurostag-tutorial1-lf-extensions.bin b/iidm/iidm-serde/src/test/resources/V1_12/eurostag-tutorial1-lf-extensions.bin deleted file mode 100644 index 192b1c97131a1dc1edaa17152f3325ec995d12a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1743 zcmc&!O=uHQ5S~poZIb?^Eh-`iMWIl%bvIfp1z)J zR0Pjns#S`3@K%onFAIWa3!(=v-ip?P)k`m0-_P#aKWcA2$jo~)-+c3C=4}R4O))C% zqoYG(Aj;ix6nqdY>ZWR`x(0q?fi`8zQs?owUc$zpu33hj=Z;pW*RWO6jadkrbCaf} zu%O0yJ#Q&F9LMuG4{eik=752fS!|^AqMp}t74Q=qgmPHJhGOXk94V;Um{Lw+o++*t zRLg{8g!+c6WmPR_rVK?hr*)%%4G{CXl7$EfRrQoo9Gp?K95FXo*dRPgK8dG6G%Z{t zNL9lS!et9m59(zBaA$L;CO{DaASPT`6~dQ_ zFOcuaLX{);$~y3KGz9E74}Py)U%!tW?a~XV#uK4lPJ@hhoQP%O`Rv-a67|~o&Txi$ z>vz*pBU!ADkqKHMD%s5BCUUh`hXbpe8a>W{2Z|tsXyNGukBY5ER@TpEf1-|_>e0o> zhuyJm6H$eGyyU#iyedZ$6CouBPm-SSdIjVZEZDWR_9en4*fYx+%DF`r)oh~C-4h*f zJ3&2%=mdk6)0aCJ79QJ;O##HH_Z5Dqn~2A+^$$_zNt&C06YYvg8+|i&Z zo7ud(vw1|>JY4Bi?4)-TnbO-0L}CSWt0UM>H@0(a!FKM=rW6(g;v_xcKf0#}H!(D9 zzd3_7GRy%Ywtn&B^G~af2;|?`@4nZKo3|Gah5eyE9J$-3d8wPAfxb)n?xSh;Sp~Td zp{fU>n^v From 7f4d3f4a0c64bdf083a5ae4c6502342b6830739a Mon Sep 17 00:00:00 2001 From: "VIDAL Didier (Externe)" Date: Thu, 6 Jun 2024 11:55:31 +0200 Subject: [PATCH 4/7] Document the new fields Signed-off-by: VIDAL Didier (Externe) --- docs/grid_model/extensions.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/grid_model/extensions.md b/docs/grid_model/extensions.md index 16eda486842..62275678411 100644 --- a/docs/grid_model/extensions.md +++ b/docs/grid_model/extensions.md @@ -13,11 +13,13 @@ Every extension is considered as serializable unless explicitly specified as non ## Active power control This extension is used to configure the participation factor of the generator, typically in the case of a load flow computation with distributed slack enabled (with [balance type](../simulation/powerflow/index.md#balanceType) on generator). This extension is attached to a [generator](network_subnetwork.md#generator) or a [battery](network_subnetwork.md#battery). -| Attribute | Type | Unit | Required | Default value | Description | -|----------------------|---------|------------------------|----------|---------------|----------------------------------------------| -| participate | boolean | - | yes | - | The participation status | -| droop | double | None (repartition key) | no | - | The participation factor equals Pmax / droop | -| participation factor | double | None (repartition key) | no | - | Defines the participation factor explicitly | +| Attribute | Type | Unit | Required | Default value | Description | +|----------------------|---------|------------------------|----------|---------------|---------------------------------------------------------------------------------------| +| participate | boolean | - | yes | - | The participation status | +| droop | double | None (repartition key) | no | - | The participation factor equals Pmax / droop | +| participation factor | double | None (repartition key) | no | - | Defines the participation factor explicitly | +| maxP override | double | MW | no | - | If defined, this limit is used for slack distribution instead of the generator's maxP | +| minP override | double | MW | no | - | if defined, this limit is used for slack distribution instead of the generator's minP | Here is how to add an active power control extension to a generator: ```java @@ -28,7 +30,7 @@ generator.newExtension(ActivePowerControlAdder.class) .add(); ``` -The participation status and the participation factor are multi-variants: they can vary from one variant to another. +The participation status, the participation factor, the maxP override and the minP override are multi-variants: they can vary from one variant to another. This extension is provided by the `com.powsybl:powsybl-iidm-extensions` module. From 83ba2dfc05e0e246ec8ce80406b2b68768d2cefb Mon Sep 17 00:00:00 2001 From: "VIDAL Didier (Externe)" Date: Fri, 7 Jun 2024 13:29:28 +0200 Subject: [PATCH 5/7] anti dislexia fix Signed-off-by: VIDAL Didier (Externe) --- .../iidm/network/extensions/ActivePowerControl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java index b1be4c77a4b..23980ec47d2 100644 --- a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java +++ b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java @@ -57,24 +57,24 @@ default String getName() { void setParticipationFactor(double participationFactor); /** - * @return if present, provides the overridden value of pmin to be used for active power control operations. + * @return if present, provides the overridden value of minP to be used for active power control operations. */ Optional getMinPOverride(); /** * Sets the overridden minimal active power. - * @param pMinOverride The overridden value of Pmin. A Nan value removes the override. + * @param pMinOverride The overridden value of minP. A Nan value removes the override. */ void setMinPOverride(double pMinOverride); /** - * @return if present, provides the overridden value of pmax to be used for active power control operations. + * @return if present, provides the overridden value of maxP to be used for active power control operations. */ Optional getMaxPOverride(); /** * Sets the overridden maximal active power. - * @param pMaxOverride The overridden value of Pmax. A Nan value removes the override. + * @param pMaxOverride The overridden value of maxP. A Nan value removes the override. */ void setMaxPOverride(double pMaxOverride); } From 44b529e080dd04563dac7cb1b34b594f6e9fead1 Mon Sep 17 00:00:00 2001 From: "VIDAL Didier (Externe)" Date: Fri, 7 Jun 2024 13:52:42 +0200 Subject: [PATCH 6/7] align on freshly defined convention :-) Signed-off-by: VIDAL Didier (Externe) --- docs/grid_model/extensions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/grid_model/extensions.md b/docs/grid_model/extensions.md index 62275678411..dd9786ad4e0 100644 --- a/docs/grid_model/extensions.md +++ b/docs/grid_model/extensions.md @@ -16,7 +16,7 @@ This extension is used to configure the participation factor of the generator, t | Attribute | Type | Unit | Required | Default value | Description | |----------------------|---------|------------------------|----------|---------------|---------------------------------------------------------------------------------------| | participate | boolean | - | yes | - | The participation status | -| droop | double | None (repartition key) | no | - | The participation factor equals Pmax / droop | +| droop | double | None (repartition key) | no | - | The participation factor equals maxP / droop | | participation factor | double | None (repartition key) | no | - | Defines the participation factor explicitly | | maxP override | double | MW | no | - | If defined, this limit is used for slack distribution instead of the generator's maxP | | minP override | double | MW | no | - | if defined, this limit is used for slack distribution instead of the generator's minP | From 0ac02bd62f0adccc72b8fe2d2522cc7beb2c8f81 Mon Sep 17 00:00:00 2001 From: "VIDAL Didier (Externe)" Date: Tue, 11 Jun 2024 15:27:36 +0200 Subject: [PATCH 7/7] review remarks Signed-off-by: VIDAL Didier (Externe) --- .../iidm/network/extensions/ActivePowerControl.java | 6 +++--- .../impl/extensions/ActivePowerControlImpl.java | 10 +++++----- .../iidm/serde/extensions/ActivePowerControlSerDe.java | 10 ++++++---- .../serde/extensions/ActivePowerControlXmlTest.java | 5 +++-- .../tck/extensions/AbstractActivePowerControlTest.java | 8 ++++---- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java index 23980ec47d2..af9dc407473 100644 --- a/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java +++ b/iidm/iidm-extensions/src/main/java/com/powsybl/iidm/network/extensions/ActivePowerControl.java @@ -10,7 +10,7 @@ import com.powsybl.commons.extensions.Extension; import com.powsybl.iidm.network.Injection; -import java.util.Optional; +import java.util.OptionalDouble; /** * @author Ghiles Abdellah {@literal } @@ -59,7 +59,7 @@ default String getName() { /** * @return if present, provides the overridden value of minP to be used for active power control operations. */ - Optional getMinPOverride(); + OptionalDouble getMinPOverride(); /** * Sets the overridden minimal active power. @@ -70,7 +70,7 @@ default String getName() { /** * @return if present, provides the overridden value of maxP to be used for active power control operations. */ - Optional getMaxPOverride(); + OptionalDouble getMaxPOverride(); /** * Sets the overridden maximal active power. diff --git a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java index 05acf498c3d..c890aabe86e 100644 --- a/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java +++ b/iidm/iidm-impl/src/main/java/com/powsybl/iidm/network/impl/extensions/ActivePowerControlImpl.java @@ -14,7 +14,7 @@ import gnu.trove.list.array.TDoubleArrayList; import java.util.List; -import java.util.Optional; +import java.util.OptionalDouble; /** * @author Ghiles Abdellah {@literal } @@ -116,9 +116,9 @@ public void allocateVariantArrayElement(int[] indexes, int sourceIndex) { } @Override - public Optional getMinPOverride() { + public OptionalDouble getMinPOverride() { double result = minPOverride.get(getVariantIndex()); - return Double.isNaN(result) ? Optional.empty() : Optional.of(result); + return Double.isNaN(result) ? OptionalDouble.empty() : OptionalDouble.of(result); } @Override @@ -127,9 +127,9 @@ public void setMinPOverride(double minPOverride) { } @Override - public Optional getMaxPOverride() { + public OptionalDouble getMaxPOverride() { double result = maxPOverride.get(getVariantIndex()); - return Double.isNaN(result) ? Optional.empty() : Optional.of(result); + return Double.isNaN(result) ? OptionalDouble.empty() : OptionalDouble.of(result); } @Override diff --git a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/extensions/ActivePowerControlSerDe.java b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/extensions/ActivePowerControlSerDe.java index 44eb773c27b..fc1507962ae 100644 --- a/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/extensions/ActivePowerControlSerDe.java +++ b/iidm/iidm-serde/src/main/java/com/powsybl/iidm/serde/extensions/ActivePowerControlSerDe.java @@ -65,8 +65,9 @@ public void write(ActivePowerControl activePowerControl, SerializerContext co context.getWriter().writeDoubleAttribute("participationFactor", activePowerControl.getParticipationFactor()); } if ("1.2".compareTo(extVersionStr) <= 0) { - context.getWriter().writeOptionalDoubleAttribute("maxPOverride", activePowerControl.getMaxPOverride().orElse(null)); - context.getWriter().writeOptionalDoubleAttribute("minPOverride", activePowerControl.getMinPOverride().orElse(null)); + // not using writeOptionalDouble and trusting implementation convention: : writeDoubleAttribute does not write NaN values in human-readable formats JSON/XML + context.getWriter().writeDoubleAttribute("maxPOverride", activePowerControl.getMaxPOverride().orElse(Double.NaN)); + context.getWriter().writeDoubleAttribute("minPOverride", activePowerControl.getMinPOverride().orElse(Double.NaN)); } } @@ -95,8 +96,9 @@ public ActivePowerControl read(T identifiable, DeserializerContext context) { participationFactor = context.getReader().readDoubleAttribute("participationFactor"); } if ("1.2".compareTo(extVersionStr) <= 0) { - maxPOverride = context.getReader().readOptionalDoubleAttribute("maxPOverride").orElse(Double.NaN); - minPOverride = context.getReader().readOptionalDoubleAttribute("minPOverride").orElse(Double.NaN); + // not using readOptionalDouble and trusting implementation convention: readDoubleAttribute returns Nan if attribute is absent in human-readable formats (JSON / XML) + maxPOverride = context.getReader().readDoubleAttribute("maxPOverride"); + minPOverride = context.getReader().readDoubleAttribute("minPOverride"); } context.getReader().readEndNode(); ActivePowerControlAdder activePowerControlAdder = identifiable.newExtension(ActivePowerControlAdder.class); diff --git a/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/extensions/ActivePowerControlXmlTest.java b/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/extensions/ActivePowerControlXmlTest.java index cd6ec779c41..613e0a6b5f9 100644 --- a/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/extensions/ActivePowerControlXmlTest.java +++ b/iidm/iidm-serde/src/test/java/com/powsybl/iidm/serde/extensions/ActivePowerControlXmlTest.java @@ -19,6 +19,7 @@ import org.junit.jupiter.api.Test; import java.io.IOException; +import java.util.OptionalDouble; import static com.powsybl.iidm.serde.IidmSerDeConstants.CURRENT_IIDM_VERSION; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -55,7 +56,7 @@ void testPLimitOverride() throws IOException { assertNotNull(gen2); ActivePowerControl activePowerControl1 = gen2.getExtension(ActivePowerControl.class); assertNotNull(activePowerControl1); - assertEquals(100, activePowerControl1.getMaxPOverride().get()); + assertEquals(OptionalDouble.of(100), activePowerControl1.getMaxPOverride()); assertTrue(activePowerControl1.getMinPOverride().isEmpty()); Battery bat2 = network2.getBattery("BAT"); @@ -63,7 +64,7 @@ void testPLimitOverride() throws IOException { ActivePowerControl activePowerControl2 = bat2.getExtension(ActivePowerControl.class); assertNotNull(activePowerControl2); assertTrue(activePowerControl2.getMaxPOverride().isEmpty()); - assertEquals(10, activePowerControl2.getMinPOverride().get()); + assertEquals(OptionalDouble.of(10), activePowerControl2.getMinPOverride()); } @Test diff --git a/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java b/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java index de60ea29cd0..32f2b1e213f 100644 --- a/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java +++ b/iidm/iidm-tck/src/test/java/com/powsybl/iidm/network/tck/extensions/AbstractActivePowerControlTest.java @@ -180,8 +180,8 @@ private static void checkValues3(ActivePowerControl activePowerControl) assertTrue(activePowerControl.isParticipate()); assertEquals(4.0, activePowerControl.getDroop(), 0.0); assertEquals(1.2, activePowerControl.getParticipationFactor(), 0.0); - assertEquals(10, activePowerControl.getMinPOverride().get()); - assertEquals(100, activePowerControl.getMaxPOverride().get()); + assertEquals(10, activePowerControl.getMinPOverride().getAsDouble()); + assertEquals(100, activePowerControl.getMaxPOverride().getAsDouble()); } private static void checkValues4(ActivePowerControl activePowerControl) { @@ -189,7 +189,7 @@ private static void checkValues4(ActivePowerControl activePowerControl) assertEquals(6.0, activePowerControl.getDroop(), 0.0); assertEquals(3.0, activePowerControl.getParticipationFactor(), 0.0); assertTrue(activePowerControl.getMinPOverride().isEmpty()); - assertEquals(110, activePowerControl.getMaxPOverride().get()); + assertEquals(110, activePowerControl.getMaxPOverride().getAsDouble()); } private static void checkValues5(ActivePowerControl activePowerControl) { @@ -197,6 +197,6 @@ private static void checkValues5(ActivePowerControl activePowerControl) assertEquals(6.0, activePowerControl.getDroop(), 0.0); assertEquals(3.0, activePowerControl.getParticipationFactor(), 0.0); assertTrue(activePowerControl.getMaxPOverride().isEmpty()); - assertEquals(11, activePowerControl.getMinPOverride().get()); + assertEquals(11, activePowerControl.getMinPOverride().getAsDouble()); } }