diff --git a/src/main/java/org/gridsuite/modification/modifications/ShuntCompensatorModification.java b/src/main/java/org/gridsuite/modification/modifications/ShuntCompensatorModification.java index bc153857..7834c83f 100644 --- a/src/main/java/org/gridsuite/modification/modifications/ShuntCompensatorModification.java +++ b/src/main/java/org/gridsuite/modification/modifications/ShuntCompensatorModification.java @@ -30,33 +30,32 @@ * @author Seddik Yengui */ -public class ShuntCompensatorModification extends AbstractModification { +public class ShuntCompensatorModification extends AbstractInjectionModification { private static final String SWITCHED_ON_Q_AT_NOMINALV_LOG_MESSAGE = "Switched-on Q at nominal voltage"; - private final ShuntCompensatorModificationInfos modificationInfos; - public ShuntCompensatorModification(ShuntCompensatorModificationInfos shuntCompensatorModificationInfos) { - this.modificationInfos = shuntCompensatorModificationInfos; + super(shuntCompensatorModificationInfos); } @Override public void check(Network network) throws NetworkModificationException { - ShuntCompensator shuntCompensator = network.getShuntCompensator(modificationInfos.getEquipmentId()); + ShuntCompensatorModificationInfos shuntCompensatorModificationInfos = (ShuntCompensatorModificationInfos) modificationInfos; + ShuntCompensator shuntCompensator = network.getShuntCompensator(shuntCompensatorModificationInfos.getEquipmentId()); if (shuntCompensator == null) { throw new NetworkModificationException(SHUNT_COMPENSATOR_NOT_FOUND, - String.format("Shunt compensator %s does not exist in network", modificationInfos.getEquipmentId())); + String.format("Shunt compensator %s does not exist in network", shuntCompensatorModificationInfos.getEquipmentId())); } - ModificationUtils.getInstance().checkVoltageLevelModification(network, modificationInfos.getVoltageLevelId(), - modificationInfos.getBusOrBusbarSectionId(), shuntCompensator.getTerminal()); - int maximumSectionCount = modificationInfos.getMaximumSectionCount() != null - ? modificationInfos.getMaximumSectionCount().getValue() + ModificationUtils.getInstance().checkVoltageLevelModification(network, shuntCompensatorModificationInfos.getVoltageLevelId(), + shuntCompensatorModificationInfos.getBusOrBusbarSectionId(), shuntCompensator.getTerminal()); + int maximumSectionCount = shuntCompensatorModificationInfos.getMaximumSectionCount() != null + ? shuntCompensatorModificationInfos.getMaximumSectionCount().getValue() : shuntCompensator.getMaximumSectionCount(); - int sectionCount = modificationInfos.getSectionCount() != null - ? modificationInfos.getSectionCount().getValue() + int sectionCount = shuntCompensatorModificationInfos.getSectionCount() != null + ? shuntCompensatorModificationInfos.getSectionCount().getValue() : shuntCompensator.getSectionCount(); - if (modificationInfos.getMaximumSectionCount() != null && modificationInfos.getMaximumSectionCount().getValue() < 1) { + if (shuntCompensatorModificationInfos.getMaximumSectionCount() != null && shuntCompensatorModificationInfos.getMaximumSectionCount().getValue() < 1) { throw new NetworkModificationException(MODIFY_SHUNT_COMPENSATOR_ERROR, "Maximum section count should be greater or equal to 1"); } @@ -67,12 +66,13 @@ public void check(Network network) throws NetworkModificationException { @Override public void apply(Network network, ReportNode subReportNode) { - ShuntCompensator shuntCompensator = network.getShuntCompensator(modificationInfos.getEquipmentId()); + ShuntCompensatorModificationInfos shuntCompensatorModificationInfos = (ShuntCompensatorModificationInfos) modificationInfos; + ShuntCompensator shuntCompensator = network.getShuntCompensator(shuntCompensatorModificationInfos.getEquipmentId()); VoltageLevel voltageLevel = shuntCompensator.getTerminal().getVoltageLevel(); subReportNode.newReportNode() .withMessageTemplate("network.modification.shuntCompensatorModification.withId") - .withUntypedValue("id", modificationInfos.getEquipmentId()) + .withUntypedValue("id", shuntCompensatorModificationInfos.getEquipmentId()) .withSeverity(TypedValue.INFO_SEVERITY) .add(); @@ -81,9 +81,10 @@ public void apply(Network network, ReportNode subReportNode) { if (shuntCompensator.getModelType() == ShuntCompensatorModelType.LINEAR) { applyModificationOnLinearModel(subReportNode, shuntCompensator, voltageLevel); } - modifyShuntCompensatorVoltageLevelBusOrBusBarSectionAttributes(modificationInfos, shuntCompensator, subReportNode); - modifyShuntCompensatorConnectivityAttributes(modificationInfos, shuntCompensator, subReportNode); - PropertiesUtils.applyProperties(shuntCompensator, subReportNode, modificationInfos.getProperties(), "network.modification.ShuntCompensatorProperties"); + modifyShuntCompensatorVoltageLevelBusOrBusBarSectionAttributes(shuntCompensatorModificationInfos, shuntCompensator, subReportNode); + modifyShuntCompensatorConnectivityAttributes(shuntCompensatorModificationInfos, shuntCompensator, subReportNode); + updateMeasurements(shuntCompensator, shuntCompensatorModificationInfos, subReportNode); + PropertiesUtils.applyProperties(shuntCompensator, subReportNode, shuntCompensatorModificationInfos.getProperties(), "network.modification.ShuntCompensatorProperties"); } @Override @@ -120,6 +121,7 @@ public static void modifySectionCount(AttributeModification sectionCoun } private void applyModificationOnLinearModel(ReportNode subReportNode, ShuntCompensator shuntCompensator, VoltageLevel voltageLevel) { + ShuntCompensatorModificationInfos shuntCompensatorModificationInfos = (ShuntCompensatorModificationInfos) modificationInfos; List reports = new ArrayList<>(); ShuntCompensatorLinearModel model = shuntCompensator.getModel(ShuntCompensatorLinearModel.class); var shuntCompensatorType = model.getBPerSection() > 0 ? ShuntCompensatorType.CAPACITOR : ShuntCompensatorType.REACTOR; @@ -129,33 +131,33 @@ private void applyModificationOnLinearModel(ReportNode subReportNode, ShuntCompe double oldSwitchedOnSusceptance = oldSusceptancePerSection * shuntCompensator.getSectionCount(); double oldSwitchedOnQAtNominalV = oldQAtNominalV * shuntCompensator.getSectionCount(); - if (modificationInfos.getShuntCompensatorType() != null || modificationInfos.getMaxQAtNominalV() != null) { - modificationInfos.setMaxSusceptance(null); + if (shuntCompensatorModificationInfos.getShuntCompensatorType() != null || shuntCompensatorModificationInfos.getMaxQAtNominalV() != null) { + shuntCompensatorModificationInfos.setMaxSusceptance(null); } // due to cross validation between maximum section count and section count, we need to modify section count first // when maximum section count old value is greater than the new one - if (modificationInfos.getMaximumSectionCount() != null && modificationInfos.getMaximumSectionCount().getValue() < shuntCompensator.getMaximumSectionCount()) { - modifySectionCount(modificationInfos.getSectionCount(), reports, shuntCompensator); - modifyMaximumSectionCount(modificationInfos.getMaximumSectionCount(), - modificationInfos.getMaxSusceptance(), - modificationInfos.getMaxQAtNominalV(), + if (shuntCompensatorModificationInfos.getMaximumSectionCount() != null && shuntCompensatorModificationInfos.getMaximumSectionCount().getValue() < shuntCompensator.getMaximumSectionCount()) { + modifySectionCount(shuntCompensatorModificationInfos.getSectionCount(), reports, shuntCompensator); + modifyMaximumSectionCount(shuntCompensatorModificationInfos.getMaximumSectionCount(), + shuntCompensatorModificationInfos.getMaxSusceptance(), + shuntCompensatorModificationInfos.getMaxQAtNominalV(), reports, shuntCompensator, model); } else { - modifyMaximumSectionCount(modificationInfos.getMaximumSectionCount(), - modificationInfos.getMaxSusceptance(), - modificationInfos.getMaxQAtNominalV(), + modifyMaximumSectionCount(shuntCompensatorModificationInfos.getMaximumSectionCount(), + shuntCompensatorModificationInfos.getMaxSusceptance(), + shuntCompensatorModificationInfos.getMaxQAtNominalV(), reports, shuntCompensator, model); - modifySectionCount(modificationInfos.getSectionCount(), reports, shuntCompensator); + modifySectionCount(shuntCompensatorModificationInfos.getSectionCount(), reports, shuntCompensator); } - int maximumSectionCount = modificationInfos.getMaximumSectionCount() != null ? modificationInfos.getMaximumSectionCount().getValue() : shuntCompensator.getMaximumSectionCount(); - int sectionCount = modificationInfos.getSectionCount() != null ? modificationInfos.getSectionCount().getValue() : shuntCompensator.getSectionCount(); + int maximumSectionCount = shuntCompensatorModificationInfos.getMaximumSectionCount() != null ? shuntCompensatorModificationInfos.getMaximumSectionCount().getValue() : shuntCompensator.getMaximumSectionCount(); + int sectionCount = shuntCompensatorModificationInfos.getSectionCount() != null ? shuntCompensatorModificationInfos.getSectionCount().getValue() : shuntCompensator.getSectionCount(); - if (modificationInfos.getShuntCompensatorType() != null) { - reports.add(ModificationUtils.getInstance().buildModificationReport(shuntCompensatorType, modificationInfos.getShuntCompensatorType().getValue(), "Type")); - shuntCompensatorType = modificationInfos.getShuntCompensatorType().getValue(); - if (modificationInfos.getMaxQAtNominalV() == null) { + if (shuntCompensatorModificationInfos.getShuntCompensatorType() != null) { + reports.add(ModificationUtils.getInstance().buildModificationReport(shuntCompensatorType, shuntCompensatorModificationInfos.getShuntCompensatorType().getValue(), "Type")); + shuntCompensatorType = shuntCompensatorModificationInfos.getShuntCompensatorType().getValue(); + if (shuntCompensatorModificationInfos.getMaxQAtNominalV() == null) { // we retrieve the absolute value of susceptance per section, then we determine the sign using the type double bPerSectionAbsoluteValue = Math.abs(oldSusceptancePerSection); double newBPerSection = shuntCompensatorType == ShuntCompensatorType.CAPACITOR ? bPerSectionAbsoluteValue : -bPerSectionAbsoluteValue; @@ -163,11 +165,11 @@ private void applyModificationOnLinearModel(ReportNode subReportNode, ShuntCompe } } - if (modificationInfos.getMaxQAtNominalV() != null) { - modifyMaximumQAtNominalVoltage(modificationInfos.getMaxQAtNominalV(), voltageLevel, maximumSectionCount, reports, model, shuntCompensatorType); + if (shuntCompensatorModificationInfos.getMaxQAtNominalV() != null) { + modifyMaximumQAtNominalVoltage(shuntCompensatorModificationInfos.getMaxQAtNominalV(), voltageLevel, maximumSectionCount, reports, model, shuntCompensatorType); } - if (modificationInfos.getMaxSusceptance() != null) { - modifyMaxSusceptance(modificationInfos.getMaxSusceptance(), maximumSectionCount, reports, model); + if (shuntCompensatorModificationInfos.getMaxSusceptance() != null) { + modifyMaxSusceptance(shuntCompensatorModificationInfos.getMaxSusceptance(), maximumSectionCount, reports, model); } reportSwitchedOnAndPerSectionValues(reports, oldQAtNominalV, oldSwitchedOnQAtNominalV, oldSusceptancePerSection, oldSwitchedOnSusceptance, oldMaxQAtNominalV, sectionCount, maximumSectionCount); @@ -211,22 +213,23 @@ public static void modifyMaximumQAtNominalVoltage(AttributeModification } private void reportSwitchedOnAndPerSectionValues(List reports, double oldQAtNominalV, double oldSwitchedOnQAtNominalV, double oldSusceptancePerSection, double oldSwitchedOnSusceptance, double oldMaxQAtNominalV, int sectionCount, int maximumSectionCount) { - if (modificationInfos.getMaxQAtNominalV() != null) { - double newQatNominalV = modificationInfos.getMaxQAtNominalV().getValue() / maximumSectionCount; + ShuntCompensatorModificationInfos shuntCompensatorModificationInfos = (ShuntCompensatorModificationInfos) modificationInfos; + if (shuntCompensatorModificationInfos.getMaxQAtNominalV() != null) { + double newQatNominalV = shuntCompensatorModificationInfos.getMaxQAtNominalV().getValue() / maximumSectionCount; double newSwitchedOnQAtNominalV = newQatNominalV * sectionCount; reports.add(ModificationUtils.getInstance().buildModificationReport(oldQAtNominalV, newQatNominalV, "Q at nominal voltage per section")); reports.add(ModificationUtils.getInstance().buildModificationReport(oldSwitchedOnQAtNominalV, newSwitchedOnQAtNominalV, SWITCHED_ON_Q_AT_NOMINALV_LOG_MESSAGE)); - } else if (modificationInfos.getMaxSusceptance() != null) { - double newSusceptancePerSection = modificationInfos.getMaxSusceptance().getValue() / maximumSectionCount; + } else if (shuntCompensatorModificationInfos.getMaxSusceptance() != null) { + double newSusceptancePerSection = shuntCompensatorModificationInfos.getMaxSusceptance().getValue() / maximumSectionCount; double newSwitchedOnSusceptance = newSusceptancePerSection * sectionCount; reports.add(ModificationUtils.getInstance().buildModificationReport(oldSusceptancePerSection, newSusceptancePerSection, "Susceptance per section")); reports.add(ModificationUtils.getInstance().buildModificationReport(oldSwitchedOnSusceptance, newSwitchedOnSusceptance, "Switched-on susceptance")); - } else if (modificationInfos.getMaximumSectionCount() != null) { + } else if (shuntCompensatorModificationInfos.getMaximumSectionCount() != null) { double newQatNominalV = oldMaxQAtNominalV / maximumSectionCount; double newSwitchedOnQAtNominalV = newQatNominalV * sectionCount; reports.add(ModificationUtils.getInstance().buildModificationReport(oldQAtNominalV, newQatNominalV, "Q at nominal voltage per section")); reports.add(ModificationUtils.getInstance().buildModificationReport(oldSwitchedOnQAtNominalV, newSwitchedOnQAtNominalV, SWITCHED_ON_Q_AT_NOMINALV_LOG_MESSAGE)); - } else if (modificationInfos.getSectionCount() != null) { + } else if (shuntCompensatorModificationInfos.getSectionCount() != null) { double newSwitchedOnQAtNominalV = oldQAtNominalV * sectionCount; reports.add(ModificationUtils.getInstance().buildModificationReport(oldSwitchedOnQAtNominalV, newSwitchedOnQAtNominalV, SWITCHED_ON_Q_AT_NOMINALV_LOG_MESSAGE)); } diff --git a/src/test/java/org/gridsuite/modification/modifications/ShuntCompensatorModificationTest.java b/src/test/java/org/gridsuite/modification/modifications/ShuntCompensatorModificationTest.java index d078000c..abdaa208 100644 --- a/src/test/java/org/gridsuite/modification/modifications/ShuntCompensatorModificationTest.java +++ b/src/test/java/org/gridsuite/modification/modifications/ShuntCompensatorModificationTest.java @@ -7,22 +7,25 @@ package org.gridsuite.modification.modifications; import com.fasterxml.jackson.core.type.TypeReference; -import com.powsybl.iidm.network.Network; -import com.powsybl.iidm.network.ShuntCompensatorLinearModel; -import com.powsybl.iidm.network.VoltageLevel; +import com.powsybl.iidm.network.*; import com.powsybl.iidm.network.extensions.ConnectablePosition; +import com.powsybl.iidm.network.extensions.Measurement; +import com.powsybl.iidm.network.extensions.Measurements; +import org.apache.commons.collections4.CollectionUtils; import org.gridsuite.modification.NetworkModificationException; import org.gridsuite.modification.dto.*; import org.gridsuite.modification.utils.NetworkCreation; import org.junit.jupiter.api.Test; + +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.UUID; +import static org.assertj.core.api.Assertions.assertThat; import static org.gridsuite.modification.utils.NetworkUtil.createShuntCompensator; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; /** * @author Seddik Yengui @@ -31,6 +34,8 @@ class ShuntCompensatorModificationTest extends AbstractInjectionModificationTest { private static final String PROPERTY_NAME = "property-name"; private static final String PROPERTY_VALUE = "property-value"; + private static final Double MEASUREMENT_Q_VALUE = 10.0; + private static final Boolean MEASUREMENT_Q_VALID = true; @Override protected Network createNetwork(UUID networkUuid) { @@ -211,6 +216,8 @@ protected ModificationInfos buildModification() { .maxQAtNominalV(new AttributeModification<>(15.0, OperationType.SET)) .maximumSectionCount(new AttributeModification<>(1, OperationType.SET)) .sectionCount(new AttributeModification<>(1, OperationType.SET)) + .qMeasurementValue(new AttributeModification<>(MEASUREMENT_Q_VALUE, OperationType.SET)) + .qMeasurementValidity(new AttributeModification<>(MEASUREMENT_Q_VALID, OperationType.SET)) .properties(List.of(FreePropertyInfos.builder().name(PROPERTY_NAME).value(PROPERTY_VALUE).build())) .build(); @@ -223,6 +230,7 @@ protected void assertAfterNetworkModificationApplication() { assertNotNull(model); assertEquals(2.9629E-4, model.getBPerSection(), 0.0001); assertEquals(PROPERTY_VALUE, getNetwork().getShuntCompensator("v7shunt").getProperty(PROPERTY_NAME)); + assertMeasurements(shuntCompensator); } @Override @@ -255,4 +263,12 @@ void testConnection() throws Exception { .build(); assertChangeConnectionState(getNetwork().getShuntCompensator("v2shunt"), shuntModificationInfos, true); } + + private void assertMeasurements(ShuntCompensator shuntCompensator) { + Measurements measurements = (Measurements) shuntCompensator.getExtension(Measurements.class); + assertNotNull(measurements); + Collection reactivePowerMeasurements = measurements.getMeasurements(Measurement.Type.REACTIVE_POWER).stream().toList(); + assertFalse(CollectionUtils.isEmpty(reactivePowerMeasurements)); + assertThat(reactivePowerMeasurements).allMatch(m -> m.getValue() == MEASUREMENT_Q_VALUE && m.isValid() == MEASUREMENT_Q_VALID); + } }