From bc457485c4a98a8bb41b05bae4c87c6dafa9e109 Mon Sep 17 00:00:00 2001 From: Mathieu Deharbe <148252167+Mathieu-Deharbe@users.noreply.github.com> Date: Thu, 26 Sep 2024 10:07:05 +0200 Subject: [PATCH 1/6] share code for regular network modifications and network modifications by formula (#524) Signed-off-by: Mathieu DEHARBE --- .../formula/equipmentfield/BatteryField.java | 38 +- .../equipmentfield/GeneratorField.java | 116 ++---- .../dto/formula/equipmentfield/LoadField.java | 9 +- .../equipmentfield/ShuntCompensatorField.java | 28 +- .../TwoWindingsTransformerField.java | 43 ++- .../equipmentfield/VoltageLevelField.java | 30 +- .../modifications/BatteryModification.java | 44 ++- .../modifications/ByFormulaModification.java | 5 +- .../modifications/GeneratorModification.java | 200 +++++++---- .../modifications/LoadModification.java | 13 +- .../modifications/ModificationUtils.java | 38 +- .../ShuntCompensatorModification.java | 94 +++-- .../TwoWindingsTransformerModification.java | 334 +++++++++++------- .../VoltageLevelModification.java | 99 ++++-- .../GeneratorByFormulaModificationTest.java | 4 +- 15 files changed, 666 insertions(+), 429 deletions(-) diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/BatteryField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/BatteryField.java index 079dd8a12..7c82638e7 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/BatteryField.java +++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/BatteryField.java @@ -10,6 +10,14 @@ import com.powsybl.iidm.network.Battery; import com.powsybl.iidm.network.extensions.ActivePowerControl; import com.powsybl.iidm.network.extensions.ActivePowerControlAdder; +import jakarta.validation.constraints.NotNull; +import org.gridsuite.modification.server.dto.AttributeModification; +import org.gridsuite.modification.server.dto.OperationType; +import org.gridsuite.modification.server.modifications.ModificationUtils; + +import static org.gridsuite.modification.server.NetworkModificationException.Type.MODIFY_BATTERY_ERROR; +import static org.gridsuite.modification.server.modifications.BatteryModification.modifyBatteryActiveLimitsAttributes; +import static org.gridsuite.modification.server.modifications.BatteryModification.modifyBatterySetpointsAttributes; /** * @author Seddik Yengui @@ -34,16 +42,30 @@ public static Double getReferenceValue(Battery battery, String batteryField) { }; } - public static void setNewValue(Battery battery, String batteryField, Double newValue) { + public static void setNewValue(Battery battery, String batteryField, @NotNull Double newValue) { BatteryField field = BatteryField.valueOf(batteryField); + final AttributeModification attributeModification = new AttributeModification<>(newValue, OperationType.SET); switch (field) { - case MINIMUM_ACTIVE_POWER -> battery.setMinP(newValue); - case MAXIMUM_ACTIVE_POWER -> battery.setMaxP(newValue); - case ACTIVE_POWER_SET_POINT -> battery.setTargetP(newValue); - case REACTIVE_POWER_SET_POINT -> battery.setTargetQ(newValue); - case DROOP -> battery.newExtension(ActivePowerControlAdder.class) - .withDroop(newValue) - .add(); + case MINIMUM_ACTIVE_POWER -> + modifyBatteryActiveLimitsAttributes(null, attributeModification, battery, null); + case MAXIMUM_ACTIVE_POWER -> + modifyBatteryActiveLimitsAttributes(attributeModification, null, battery, null); + case ACTIVE_POWER_SET_POINT -> { + ModificationUtils.getInstance().checkActivePowerZeroOrBetweenMinAndMaxActivePower( + attributeModification, null, null, battery.getMinP(), + battery.getMaxP(), battery.getTargetP(), MODIFY_BATTERY_ERROR, "Battery '" + battery.getId() + "' : " + ); + modifyBatterySetpointsAttributes(attributeModification, null, null, null, battery, null); + } + case REACTIVE_POWER_SET_POINT -> modifyBatterySetpointsAttributes( + null, attributeModification, null, null, battery, null); + case DROOP -> { + ActivePowerControl activePowerControl = battery.getExtension(ActivePowerControl.class); + ActivePowerControlAdder activePowerControlAdder = battery.newExtension(ActivePowerControlAdder.class); + ModificationUtils.getInstance().modifyActivePowerControlAttributes( + activePowerControl, activePowerControlAdder, null, + new AttributeModification<>(newValue.floatValue(), OperationType.SET), null, null); + } } } } diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java index 7c864cbfd..d36390c58 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java +++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java @@ -11,11 +11,15 @@ import com.powsybl.iidm.network.extensions.ActivePowerControl; import com.powsybl.iidm.network.extensions.ActivePowerControlAdder; import com.powsybl.iidm.network.extensions.CoordinatedReactiveControl; -import com.powsybl.iidm.network.extensions.CoordinatedReactiveControlAdder; import com.powsybl.iidm.network.extensions.GeneratorShortCircuit; -import com.powsybl.iidm.network.extensions.GeneratorShortCircuitAdder; import com.powsybl.iidm.network.extensions.GeneratorStartup; -import com.powsybl.iidm.network.extensions.GeneratorStartupAdder; +import com.powsybl.network.store.iidm.impl.extensions.CoordinatedReactiveControlAdderImpl; +import org.gridsuite.modification.server.dto.AttributeModification; +import org.gridsuite.modification.server.dto.OperationType; +import org.gridsuite.modification.server.modifications.ModificationUtils; + +import static org.gridsuite.modification.server.NetworkModificationException.Type.MODIFY_GENERATOR_ERROR; +import static org.gridsuite.modification.server.modifications.GeneratorModification.*; /** * @author Seddik Yengui @@ -61,86 +65,42 @@ public static Double getReferenceValue(Generator generator, String generatorFiel }; } - public static void setNewValue(Generator generator, String generatorField, Double newValue) { + public static void setNewValue(Generator generator, String generatorField, double newValue) { if (!Double.isNaN(newValue)) { - GeneratorStartup generatorStartup = generator.getExtension(GeneratorStartup.class); - GeneratorShortCircuit generatorShortCircuit = generator.getExtension(GeneratorShortCircuit.class); GeneratorField field = GeneratorField.valueOf(generatorField); + final AttributeModification attributeModification = new AttributeModification<>(newValue, OperationType.SET); switch (field) { - case MAXIMUM_ACTIVE_POWER -> generator.setMaxP(newValue); - case MINIMUM_ACTIVE_POWER -> generator.setMinP(newValue); - case ACTIVE_POWER_SET_POINT -> generator.setTargetP(newValue); - case RATED_NOMINAL_POWER -> generator.setRatedS(newValue); - case REACTIVE_POWER_SET_POINT -> generator.setTargetQ(newValue); - case VOLTAGE_SET_POINT -> generator.setTargetV(newValue); - case PLANNED_ACTIVE_POWER_SET_POINT -> { - if (generatorStartup == null) { - generator.newExtension(GeneratorStartupAdder.class) - .withPlannedActivePowerSetpoint(newValue) - .add(); - } else { - generator.newExtension(GeneratorStartupAdder.class) - .withMarginalCost(generatorStartup.getMarginalCost()) - .withPlannedActivePowerSetpoint(newValue) - .withPlannedOutageRate(generatorStartup.getPlannedOutageRate()) - .withForcedOutageRate(generatorStartup.getForcedOutageRate()) - .add(); - } - } - case MARGINAL_COST -> { - if (generatorStartup == null) { - generator.newExtension(GeneratorStartupAdder.class) - .withMarginalCost(newValue) - .add(); - } else { - generator.newExtension(GeneratorStartupAdder.class) - .withMarginalCost(newValue) - .withPlannedActivePowerSetpoint(generatorStartup.getPlannedActivePowerSetpoint()) - .withPlannedOutageRate(generatorStartup.getPlannedOutageRate()) - .withForcedOutageRate(generatorStartup.getForcedOutageRate()) - .add(); - } - } - case PLANNED_OUTAGE_RATE -> { - if (generatorStartup == null) { - generator.newExtension(GeneratorStartupAdder.class) - .withPlannedOutageRate(newValue) - .add(); - } else { - generator.newExtension(GeneratorStartupAdder.class) - .withMarginalCost(generatorStartup.getMarginalCost()) - .withPlannedActivePowerSetpoint(generatorStartup.getPlannedActivePowerSetpoint()) - .withPlannedOutageRate(newValue) - .withForcedOutageRate(generatorStartup.getForcedOutageRate()) - .add(); - } + case MAXIMUM_ACTIVE_POWER -> modifyGeneratorActiveLimitsAttributes( + attributeModification, null, null, generator, null); + case MINIMUM_ACTIVE_POWER -> modifyGeneratorActiveLimitsAttributes(null, attributeModification, null, generator, null); + case ACTIVE_POWER_SET_POINT -> { + ModificationUtils.getInstance().checkActivePowerZeroOrBetweenMinAndMaxActivePower( + attributeModification, null, null, + generator.getMinP(), generator.getMaxP(), generator.getTargetP(), + MODIFY_GENERATOR_ERROR, "Generator '" + generator.getId() + "' : " + ); + generator.setTargetP(newValue); } - case FORCED_OUTAGE_RATE -> { - if (generatorStartup == null) { - generator.newExtension(GeneratorStartupAdder.class) - .withForcedOutageRate(newValue) - .add(); - } else { - generator.newExtension(GeneratorStartupAdder.class) - .withMarginalCost(generatorStartup.getMarginalCost()) - .withPlannedActivePowerSetpoint(generatorStartup.getPlannedActivePowerSetpoint()) - .withPlannedOutageRate(generatorStartup.getForcedOutageRate()) - .withForcedOutageRate(newValue) - .add(); - } + case RATED_NOMINAL_POWER -> modifyGeneratorActiveLimitsAttributes(null, null, attributeModification, generator, null); + case REACTIVE_POWER_SET_POINT -> modifyTargetQ(generator, attributeModification); + case VOLTAGE_SET_POINT -> modifyTargetV(generator, attributeModification); + case PLANNED_ACTIVE_POWER_SET_POINT -> + modifyGeneratorStartUpAttributes(attributeModification, null, null, null, generator, null, null); + case MARGINAL_COST -> + modifyGeneratorStartUpAttributes(null, attributeModification, null, null, generator, null, null); + case PLANNED_OUTAGE_RATE -> + modifyGeneratorStartUpAttributes(null, null, attributeModification, null, generator, null, null); + case FORCED_OUTAGE_RATE -> + modifyGeneratorStartUpAttributes(null, null, null, attributeModification, generator, null, null); + case DROOP -> { + ActivePowerControl activePowerControl = generator.getExtension(ActivePowerControl.class); + ActivePowerControlAdder activePowerControlAdder = generator.newExtension(ActivePowerControlAdder.class); + ModificationUtils.getInstance().modifyActivePowerControlAttributes(activePowerControl, activePowerControlAdder, null, + new AttributeModification<>((float) newValue, OperationType.SET), null, null); } - case DROOP -> generator.newExtension(ActivePowerControlAdder.class) - .withDroop(newValue) - .add(); - case TRANSIENT_REACTANCE -> generator.newExtension(GeneratorShortCircuitAdder.class) - .withDirectTransX(newValue) - .withStepUpTransformerX(generatorShortCircuit == null ? Double.NaN : generatorShortCircuit.getStepUpTransformerX()) - .add(); - case STEP_UP_TRANSFORMER_REACTANCE -> generator.newExtension(GeneratorShortCircuitAdder.class) - .withDirectTransX(generatorShortCircuit == null ? 0.0D : generatorShortCircuit.getDirectTransX()) - .withStepUpTransformerX(newValue) - .add(); - case Q_PERCENT -> generator.newExtension(CoordinatedReactiveControlAdder.class) + case TRANSIENT_REACTANCE -> modifyGeneratorShortCircuitAttributes(attributeModification, null, generator, null); + case STEP_UP_TRANSFORMER_REACTANCE -> modifyGeneratorShortCircuitAttributes(null, attributeModification, generator, null); + case Q_PERCENT -> generator.newExtension(CoordinatedReactiveControlAdderImpl.class) .withQPercent(newValue) .add(); } diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/LoadField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/LoadField.java index 2743186a6..8c01d3f96 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/LoadField.java +++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/LoadField.java @@ -8,6 +8,11 @@ package org.gridsuite.modification.server.dto.formula.equipmentfield; import com.powsybl.iidm.network.Load; +import org.gridsuite.modification.server.dto.AttributeModification; +import org.gridsuite.modification.server.dto.OperationType; + +import static org.gridsuite.modification.server.modifications.LoadModification.modifyP0; +import static org.gridsuite.modification.server.modifications.LoadModification.modifyQ0; /** * @author Seddik Yengui @@ -28,8 +33,8 @@ public static Double getReferenceValue(Load load, String loadField) { public static void setNewValue(Load load, String loadField, Double newValue) { LoadField field = LoadField.valueOf(loadField); switch (field) { - case ACTIVE_POWER -> load.setP0(newValue); - case REACTIVE_POWER -> load.setQ0(newValue); + case ACTIVE_POWER -> modifyP0(load, new AttributeModification<>(newValue, OperationType.SET), null); + case REACTIVE_POWER -> modifyQ0(load, new AttributeModification<>(newValue, OperationType.SET), null); } } } diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/ShuntCompensatorField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/ShuntCompensatorField.java index e155d4720..87dabb14a 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/ShuntCompensatorField.java +++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/ShuntCompensatorField.java @@ -12,6 +12,11 @@ import com.powsybl.iidm.network.ShuntCompensatorModelType; import com.powsybl.iidm.network.VoltageLevel; import org.gridsuite.modification.server.NetworkModificationException; +import org.gridsuite.modification.server.dto.AttributeModification; +import org.gridsuite.modification.server.dto.OperationType; +import org.gridsuite.modification.server.dto.ShuntCompensatorType; + +import static org.gridsuite.modification.server.modifications.ShuntCompensatorModification.*; /** * @author Seddik Yengui @@ -42,19 +47,18 @@ public static void setNewValue(ShuntCompensator shuntCompensator, String shuntCo ShuntCompensatorLinearModel model = shuntCompensator.getModel(ShuntCompensatorLinearModel.class); ShuntCompensatorField field = ShuntCompensatorField.valueOf(shuntCompensatorField); VoltageLevel voltageLevel = shuntCompensator.getTerminal().getVoltageLevel(); + var shuntCompensatorType = ShuntCompensatorType.REACTOR; + if (model != null && model.getBPerSection() > 0) { + shuntCompensatorType = ShuntCompensatorType.CAPACITOR; + } switch (field) { - case MAXIMUM_SECTION_COUNT -> { - int maximumSectionCount = newValue.intValue(); - model.setBPerSection(model.getBPerSection() * shuntCompensator.getMaximumSectionCount() / maximumSectionCount); - model.setMaximumSectionCount(maximumSectionCount); - } - case SECTION_COUNT -> shuntCompensator.setSectionCount(newValue.intValue()); - case MAXIMUM_SUSCEPTANCE -> model.setBPerSection(newValue / shuntCompensator.getMaximumSectionCount()); - case MAXIMUM_Q_AT_NOMINAL_VOLTAGE -> { - double newQatNominalV = newValue / shuntCompensator.getMaximumSectionCount(); - double newSusceptancePerSection = newQatNominalV / Math.pow(voltageLevel.getNominalV(), 2); - model.setBPerSection(newSusceptancePerSection); - } + case MAXIMUM_SECTION_COUNT -> modifyMaximumSectionCount(new AttributeModification<>(newValue.intValue(), OperationType.SET), + null, null, null, shuntCompensator, model); + case SECTION_COUNT -> modifySectionCount(new AttributeModification<>(newValue.intValue(), OperationType.SET), null, shuntCompensator); + case MAXIMUM_SUSCEPTANCE -> modifyMaxSusceptance(new AttributeModification<>(newValue, OperationType.SET), + shuntCompensator.getMaximumSectionCount(), null, model); + case MAXIMUM_Q_AT_NOMINAL_VOLTAGE -> modifyMaximumQAtNominalVoltage(new AttributeModification<>(newValue, OperationType.SET), + voltageLevel, shuntCompensator.getMaximumSectionCount(), null, model, shuntCompensatorType); } } } diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java index e0f6d52df..6a13e93d6 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java +++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java @@ -3,6 +3,9 @@ import com.powsybl.iidm.network.PhaseTapChanger; import com.powsybl.iidm.network.RatioTapChanger; import com.powsybl.iidm.network.TwoWindingsTransformer; +import org.gridsuite.modification.server.dto.AttributeModification; +import org.gridsuite.modification.server.dto.OperationType; +import static org.gridsuite.modification.server.modifications.TwoWindingsTransformerModification.*; public enum TwoWindingsTransformerField { R, @@ -48,23 +51,33 @@ public static void setNewValue(TwoWindingsTransformer transformer, String twoWin TwoWindingsTransformerField field = TwoWindingsTransformerField.valueOf(twoWindingsTransformerField); final PhaseTapChanger phaseTapChanger = transformer.getPhaseTapChanger(); final RatioTapChanger ratioTapChanger = transformer.getRatioTapChanger(); + final PhaseTapChanger.RegulationMode regulationMode = phaseTapChanger != null ? phaseTapChanger.getRegulationMode() : null; + final AttributeModification attributeModification = new AttributeModification<>(newValue, OperationType.SET); switch (field) { - case R -> transformer.setR(newValue); - case X -> transformer.setX(newValue); - case G -> transformer.setG(newValue); - case B -> transformer.setB(newValue); - case RATED_U1 -> transformer.setRatedU1(newValue); - case RATED_U2 -> transformer.setRatedU2(newValue); - case RATED_S -> transformer.setRatedS(newValue); - case TARGET_V -> ratioTapChanger.setTargetV(newValue); - case RATIO_LOW_TAP_POSITION -> ratioTapChanger.setLowTapPosition(newValue.intValue()); - case RATIO_TAP_POSITION -> ratioTapChanger.setTapPosition(newValue.intValue()); - case RATIO_TARGET_DEADBAND -> ratioTapChanger.setTargetDeadband(newValue); - case REGULATION_VALUE -> phaseTapChanger.setRegulationValue(newValue); - case PHASE_LOW_TAP_POSITION -> phaseTapChanger.setLowTapPosition(newValue.intValue()); - case PHASE_TAP_POSITION -> phaseTapChanger.setTapPosition(newValue.intValue()); - case PHASE_TARGET_DEADBAND -> phaseTapChanger.setTargetDeadband(newValue); + case R -> modifyR(transformer, attributeModification, null); + case X -> modifyX(transformer, attributeModification, null); + case G -> modifyG(transformer, attributeModification, null); + case B -> modifyB(transformer, attributeModification, null); + case RATED_U1 -> modifyRatedU1(transformer, attributeModification, null); + case RATED_U2 -> modifyRatedU2(transformer, attributeModification, null); + case RATED_S -> modifyRatedS(transformer, attributeModification, null); + case TARGET_V -> modifyTargets(ratioTapChanger, null, true, attributeModification, null, null); + case RATIO_LOW_TAP_POSITION -> processTapChangerPositionsAndSteps(ratioTapChanger, null, true, + new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null, null); + case RATIO_TAP_POSITION -> processTapChangerPositionsAndSteps(ratioTapChanger, null, true, + null, new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null); + case RATIO_TARGET_DEADBAND -> modifyTargets(ratioTapChanger, null, true, null, attributeModification, null); + case REGULATION_VALUE -> processPhaseTapRegulation( + phaseTapChanger, null, regulationMode, true, attributeModification, null, null + ); + case PHASE_LOW_TAP_POSITION -> processTapChangerPositionsAndSteps(phaseTapChanger, null, true, + new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null, null); + case PHASE_TAP_POSITION -> processTapChangerPositionsAndSteps(phaseTapChanger, null, true, + null, new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null); + case PHASE_TARGET_DEADBAND -> processPhaseTapRegulation( + phaseTapChanger, null, null, true, null, attributeModification, null + ); } } } diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/VoltageLevelField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/VoltageLevelField.java index a1fc1d644..69f366ad4 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/VoltageLevelField.java +++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/VoltageLevelField.java @@ -9,7 +9,10 @@ import com.powsybl.iidm.network.VoltageLevel; import com.powsybl.iidm.network.extensions.IdentifiableShortCircuit; -import com.powsybl.iidm.network.extensions.IdentifiableShortCircuitAdder; +import org.gridsuite.modification.server.dto.AttributeModification; +import org.gridsuite.modification.server.dto.OperationType; + +import static org.gridsuite.modification.server.modifications.VoltageLevelModification.*; /** * @author Seddik Yengui @@ -35,26 +38,15 @@ public static Double getReferenceValue(VoltageLevel voltageLevel, String voltage } public static void setNewValue(VoltageLevel voltageLevel, String voltageLevelField, Double newValue) { - IdentifiableShortCircuit identifiableShortCircuit = voltageLevel.getExtension(IdentifiableShortCircuit.class); VoltageLevelField field = VoltageLevelField.valueOf(voltageLevelField); switch (field) { - case NOMINAL_VOLTAGE -> voltageLevel.setNominalV(newValue); - case LOW_VOLTAGE_LIMIT -> voltageLevel.setLowVoltageLimit(newValue); - case HIGH_VOLTAGE_LIMIT -> voltageLevel.setHighVoltageLimit(newValue); - case LOW_SHORT_CIRCUIT_CURRENT_LIMIT -> { - IdentifiableShortCircuitAdder adder = voltageLevel.newExtension(IdentifiableShortCircuitAdder.class).withIpMin(newValue); - if (identifiableShortCircuit != null) { - adder.withIpMax(identifiableShortCircuit.getIpMax()); - } - adder.add(); - } - case HIGH_SHORT_CIRCUIT_CURRENT_LIMIT -> { - IdentifiableShortCircuitAdder adder = voltageLevel.newExtension(IdentifiableShortCircuitAdder.class).withIpMax(newValue); - if (identifiableShortCircuit != null) { - adder.withIpMin(identifiableShortCircuit.getIpMin()); - } - adder.add(); - } + case NOMINAL_VOLTAGE -> modifyNominalV(voltageLevel, new AttributeModification<>(newValue, OperationType.SET), null); + case LOW_VOLTAGE_LIMIT -> modifLowVoltageLimit(voltageLevel, new AttributeModification<>(newValue, OperationType.SET), null); + case HIGH_VOLTAGE_LIMIT -> modifyHighVoltageLimit(voltageLevel, new AttributeModification<>(newValue, OperationType.SET), null); + case LOW_SHORT_CIRCUIT_CURRENT_LIMIT -> modifyVoltageLevelShortCircuit( + new AttributeModification<>(newValue, OperationType.SET), null, null, voltageLevel); + case HIGH_SHORT_CIRCUIT_CURRENT_LIMIT -> modifyVoltageLevelShortCircuit( + null, new AttributeModification<>(newValue, OperationType.SET), null, voltageLevel); } } } diff --git a/src/main/java/org/gridsuite/modification/server/modifications/BatteryModification.java b/src/main/java/org/gridsuite/modification/server/modifications/BatteryModification.java index 544be215a..15d9bd3ad 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/BatteryModification.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/BatteryModification.java @@ -18,6 +18,7 @@ import com.powsybl.iidm.network.extensions.ConnectablePosition; import com.powsybl.iidm.network.extensions.ConnectablePositionAdder; import org.gridsuite.modification.server.NetworkModificationException; +import org.gridsuite.modification.server.dto.AttributeModification; import org.gridsuite.modification.server.dto.BatteryModificationInfos; import org.gridsuite.modification.server.dto.ReactiveCapabilityCurveModificationInfos; @@ -86,17 +87,24 @@ private void modifyBattery(Battery battery, BatteryModificationInfos modificatio } modifyBatteryLimitsAttributes(modificationInfos, battery, subReportNode); - modifyBatterySetpointsAttributes(modificationInfos, battery, subReportNode); + modifyBatterySetpointsAttributes( + modificationInfos.getTargetP(), modificationInfos.getTargetQ(), + modificationInfos.getParticipate(), modificationInfos.getDroop(), + battery, subReportNode); modifyBatteryConnectivityAttributes(modificationInfos, battery, subReportNode); PropertiesUtils.applyProperties(battery, subReportNode, modificationInfos.getProperties(), "BatteryProperties"); } - private void modifyBatterySetpointsAttributes(BatteryModificationInfos modificationInfos, - Battery battery, ReportNode subReportNode) { - ReportNode reportActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setTargetP, battery::getTargetP, modificationInfos.getTargetP(), "Active power"); - ReportNode reportReactivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setTargetQ, battery::getTargetQ, modificationInfos.getTargetQ(), "Reactive power"); + public static void modifyBatterySetpointsAttributes(AttributeModification targetP, + AttributeModification targetQ, + AttributeModification participate, + AttributeModification droop, + Battery battery, + ReportNode subReportNode) { + ReportNode reportActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setTargetP, battery::getTargetP, targetP, "Active power"); + ReportNode reportReactivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setTargetQ, battery::getTargetQ, targetQ, "Reactive power"); ReportNode subReporterSetpoints = null; - if (reportActivePower != null || reportReactivePower != null) { + if (subReportNode != null && (reportActivePower != null || reportReactivePower != null)) { subReporterSetpoints = subReportNode.newReportNode().withMessageTemplate(SETPOINTS, SETPOINTS).add(); if (reportActivePower != null) { insertReportNode(subReporterSetpoints, reportActivePower); @@ -105,12 +113,12 @@ private void modifyBatterySetpointsAttributes(BatteryModificationInfos modificat insertReportNode(subReporterSetpoints, reportReactivePower); } } - modifyBatteryActivePowerControlAttributes(modificationInfos, battery, subReportNode, subReporterSetpoints); + modifyBatteryActivePowerControlAttributes(participate, droop, battery, subReportNode, subReporterSetpoints); } private void modifyBatteryLimitsAttributes(BatteryModificationInfos modificationInfos, Battery battery, ReportNode subReportNode) { - ReportNode subReportNodeLimits = modifyBatteryActiveLimitsAttributes(modificationInfos, battery, subReportNode); + ReportNode subReportNodeLimits = modifyBatteryActiveLimitsAttributes(modificationInfos.getMaxP(), modificationInfos.getMinP(), battery, subReportNode); modifyBatteryReactiveLimitsAttributes(modificationInfos, battery, subReportNode, subReportNodeLimits); } @@ -123,12 +131,13 @@ private void modifyBatteryReactiveCapabilityCurvePoints(BatteryModificationInfos ModificationUtils.getInstance().modifyReactiveCapabilityCurvePoints(points, modificationPoints, adder, subReportNode, subReportNodeLimits); } - private ReportNode modifyBatteryActiveLimitsAttributes(BatteryModificationInfos modificationInfos, - Battery battery, ReportNode subReportNode) { + public static ReportNode modifyBatteryActiveLimitsAttributes(AttributeModification maxP, + AttributeModification minP, + Battery battery, ReportNode subReportNode) { ReportNode subReportNodeLimits = null; - ReportNode reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setMaxP, battery::getMaxP, modificationInfos.getMaxP(), "Max active power"); - ReportNode reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setMinP, battery::getMinP, modificationInfos.getMinP(), "Min active power"); - if (reportMaxActivePower != null || reportMinActivePower != null) { + ReportNode reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setMaxP, battery::getMaxP, maxP, "Max active power"); + ReportNode reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setMinP, battery::getMinP, minP, "Min active power"); + if (subReportNode != null && (reportMaxActivePower != null || reportMinActivePower != null)) { subReportNodeLimits = subReportNode.newReportNode().withMessageTemplate(LIMITS, LIMITS).add(); ReportNode subReporterActiveLimits = subReportNodeLimits.newReportNode().withMessageTemplate(ACTIVE_LIMITS, ACTIVE_LIMITS).add(); if (reportMaxActivePower != null) { @@ -155,11 +164,14 @@ private void modifyBatteryReactiveLimitsAttributes(BatteryModificationInfos modi } } - private ReportNode modifyBatteryActivePowerControlAttributes(BatteryModificationInfos modificationInfos, - Battery battery, ReportNode subReportNode, ReportNode subReportNodeSetpoints) { + public static ReportNode modifyBatteryActivePowerControlAttributes(AttributeModification participate, + AttributeModification droop, + Battery battery, + ReportNode subReportNode, + ReportNode subReportNodeSetpoints) { ActivePowerControl activePowerControl = battery.getExtension(ActivePowerControl.class); ActivePowerControlAdder activePowerControlAdder = battery.newExtension(ActivePowerControlAdder.class); - return ModificationUtils.getInstance().modifyActivePowerControlAttributes(activePowerControl, activePowerControlAdder, modificationInfos.getParticipate(), modificationInfos.getDroop(), subReportNode, subReportNodeSetpoints); + return ModificationUtils.getInstance().modifyActivePowerControlAttributes(activePowerControl, activePowerControlAdder, participate, droop, subReportNode, subReportNodeSetpoints); } private ReportNode modifyBatteryConnectivityAttributes(BatteryModificationInfos modificationInfos, diff --git a/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java b/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java index 75616c713..a1f119008 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java @@ -98,7 +98,6 @@ public void apply(Network network, ReportNode subReportNode) { .withUntypedValue(KEY_VALUE, equipmentCount) .withSeverity(TypedValue.INFO_SEVERITY) .add(); - report(formulaSubReporter, formulaReports); } else { if (equipmentNotModifiedCount == equipmentCount) { createReport(subReportNode, "byFormulaModificationNone", @@ -111,9 +110,9 @@ public void apply(Network network, ReportNode subReportNode) { .withUntypedValue(KEY_NB_UNCHANGED, equipmentNotModifiedCount + equipmentNotFoundCount) .withSeverity(TypedValue.WARN_SEVERITY) .add(); - report(formulaSubReporter, formulaReports); } } + report(formulaSubReporter, formulaReports); } } @@ -267,7 +266,7 @@ private void applyFormula(Identifiable identifiable, try { final Double newValue = applyOperation(formulaInfos.getOperator(), value1, value2); switch (identifiable.getType()) { - case GENERATOR -> GeneratorField.setNewValue((Generator) identifiable, formulaInfos.getEditedField(), newValue); + case GENERATOR -> GeneratorField.setNewValue((Generator) identifiable, formulaInfos.getEditedField(), newValue.doubleValue()); case BATTERY -> BatteryField.setNewValue((Battery) identifiable, formulaInfos.getEditedField(), newValue); case SHUNT_COMPENSATOR -> ShuntCompensatorField.setNewValue((ShuntCompensator) identifiable, formulaInfos.getEditedField(), newValue); case VOLTAGE_LEVEL -> VoltageLevelField.setNewValue((VoltageLevel) identifiable, formulaInfos.getEditedField(), newValue); diff --git a/src/main/java/org/gridsuite/modification/server/modifications/GeneratorModification.java b/src/main/java/org/gridsuite/modification/server/modifications/GeneratorModification.java index 03711328c..71a4508b9 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/GeneratorModification.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/GeneratorModification.java @@ -92,53 +92,58 @@ private void modifyGenerator(Generator generator, GeneratorModificationInfos mod modifyGeneratorLimitsAttributes(modificationInfos, generator, subReportNode); modifyGeneratorSetpointsAttributes(modificationInfos, generator, subReportNode); - modifyGeneratorShortCircuitAttributes(modificationInfos, generator, subReportNode); + modifyGeneratorShortCircuitAttributes(modificationInfos.getDirectTransX(), modificationInfos.getStepUpTransformerX(), generator, subReportNode); modifyGeneratorStartUpAttributes(modificationInfos, generator, subReportNode); modifyGeneratorConnectivityAttributes(modificationInfos, generator, subReportNode); PropertiesUtils.applyProperties(generator, subReportNode, modificationInfos.getProperties(), "GeneratorProperties"); } - private void modifyGeneratorShortCircuitAttributes(GeneratorModificationInfos modificationInfos, - Generator generator, ReportNode subReportNode) { + public static void modifyGeneratorShortCircuitAttributes(AttributeModification directTransX, + AttributeModification stepUpTransformerX, + Generator generator, + ReportNode subReportNode) { List reports = new ArrayList<>(); GeneratorShortCircuit generatorShortCircuit = generator.getExtension(GeneratorShortCircuit.class); Double oldTransientReactance = generatorShortCircuit != null ? generatorShortCircuit.getDirectTransX() : Double.NaN; Double oldStepUpTransformerReactance = generatorShortCircuit != null ? generatorShortCircuit.getStepUpTransformerX() : Double.NaN; // Either transient reactance or step-up transformer reactance are modified or // both - if (modificationInfos.getDirectTransX() != null - && modificationInfos.getStepUpTransformerX() != null) { + if (directTransX != null && stepUpTransformerX != null) { generator.newExtension(GeneratorShortCircuitAdder.class) - .withDirectTransX(modificationInfos.getDirectTransX().getValue()) - .withStepUpTransformerX(modificationInfos.getStepUpTransformerX().getValue()) + .withDirectTransX(directTransX.getValue()) + .withStepUpTransformerX(stepUpTransformerX.getValue()) .add(); reports.add(ModificationUtils.getInstance().buildModificationReport( oldTransientReactance, - modificationInfos.getDirectTransX().getValue(), + directTransX.getValue(), "Transient reactance")); reports.add(ModificationUtils.getInstance().buildModificationReport( oldStepUpTransformerReactance, - modificationInfos.getStepUpTransformerX().getValue(), + stepUpTransformerX.getValue(), "Transformer reactance")); - } else if (modificationInfos.getDirectTransX() != null) { + } else if (directTransX != null) { generator.newExtension(GeneratorShortCircuitAdder.class) - .withDirectTransX(modificationInfos.getDirectTransX().getValue()) + .withStepUpTransformerX(oldStepUpTransformerReactance) + .withDirectTransX(directTransX.getValue()) .add(); reports.add(ModificationUtils.getInstance().buildModificationReport( oldTransientReactance, - modificationInfos.getDirectTransX().getValue(), + directTransX.getValue(), "Transient reactance")); - } else if (modificationInfos.getStepUpTransformerX() != null) { + } else if (stepUpTransformerX != null) { generator.newExtension(GeneratorShortCircuitAdder.class) - .withStepUpTransformerX(modificationInfos.getStepUpTransformerX().getValue()) + .withStepUpTransformerX(stepUpTransformerX.getValue()) + .withDirectTransX(oldTransientReactance) .add(); reports.add(ModificationUtils.getInstance().buildModificationReport( oldStepUpTransformerReactance, - modificationInfos.getStepUpTransformerX().getValue(), + stepUpTransformerX.getValue(), "Transformer reactance")); } - ModificationUtils.getInstance().reportModifications(subReportNode, reports, "shortCircuitAttributesModified", "Short-circuit"); + if (subReportNode != null) { + ModificationUtils.getInstance().reportModifications(subReportNode, reports, "shortCircuitAttributesModified", "Short-circuit"); + } } private void modifyGeneratorReactiveCapabilityCurvePoints(GeneratorModificationInfos modificationInfos, @@ -149,22 +154,25 @@ private void modifyGeneratorReactiveCapabilityCurvePoints(GeneratorModificationI ModificationUtils.getInstance().modifyReactiveCapabilityCurvePoints(points, modificationPoints, adder, subReportNode, subReportNodeLimits); } - private ReportNode modifyGeneratorActiveLimitsAttributes(GeneratorModificationInfos modificationInfos, - Generator generator, ReportNode subReportNode) { + public static ReportNode modifyGeneratorActiveLimitsAttributes(AttributeModification maxP, + AttributeModification minP, + AttributeModification ratedS, + Generator generator, + ReportNode subReportNode) { ReportNode subReporterLimits = null; ReportNode reportMaxActivePower; ReportNode reportMinActivePower; - if (modificationInfos.getMaxP() != null && modificationInfos.getMaxP().getValue() > generator.getMinP()) { - reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMaxP, generator::getMaxP, modificationInfos.getMaxP(), "Max active power"); - reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMinP, generator::getMinP, modificationInfos.getMinP(), "Min active power"); + if (maxP != null && maxP.getValue() > generator.getMinP()) { + reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMaxP, generator::getMaxP, maxP, "Max active power"); + reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMinP, generator::getMinP, minP, "Min active power"); } else { - reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMinP, generator::getMinP, modificationInfos.getMinP(), "Min active power"); - reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMaxP, generator::getMaxP, modificationInfos.getMaxP(), "Max active power"); + reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMinP, generator::getMinP, minP, "Min active power"); + reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMaxP, generator::getMaxP, maxP, "Max active power"); } - ReportNode reportRatedNominalPower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setRatedS, generator::getRatedS, modificationInfos.getRatedS(), "Rated nominal power"); - if (reportMaxActivePower != null || reportMinActivePower != null || reportRatedNominalPower != null) { + ReportNode reportRatedNominalPower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setRatedS, generator::getRatedS, ratedS, "Rated nominal power"); + if (subReportNode != null && (reportMaxActivePower != null || reportMinActivePower != null || reportRatedNominalPower != null)) { subReporterLimits = subReportNode.newReportNode().withMessageTemplate(LIMITS, LIMITS).add(); ReportNode subReporterActiveLimits = subReporterLimits.newReportNode().withMessageTemplate(ACTIVE_LIMITS, ACTIVE_LIMITS).add(); if (reportMaxActivePower != null) { @@ -208,30 +216,53 @@ private ReportNode modifyGeneratorActivePowerControlAttributes(GeneratorModifica private void modifyGeneratorStartUpAttributes(GeneratorModificationInfos modificationInfos, Generator generator, ReportNode subReportNode) { List reports = new ArrayList<>(); - GeneratorStartup generatorStartup = generator.getExtension(GeneratorStartup.class); + modifyGeneratorStartUpAttributes(modificationInfos.getPlannedActivePowerSetPoint(), + modificationInfos.getMarginalCost(), + modificationInfos.getPlannedOutageRate(), + modificationInfos.getForcedOutageRate(), + generator, + subReportNode, + reports); + } + + public static void modifyGeneratorStartUpAttributes(AttributeModification plannedActivePowerSetPoint, + AttributeModification marginalCost, + AttributeModification plannedOutageRate, + AttributeModification forcedOutageRate, + Generator generator, + ReportNode subReportNode, + List reports) { GeneratorStartupAdder generatorStartupAdder = generator.newExtension(GeneratorStartupAdder.class); - boolean plannedActivePowerSetPointUpdated = addPlannedActivePowerSetPoint(modificationInfos, generatorStartupAdder, generatorStartup, reports); - boolean marginalCostUpdated = addMarginalCost(modificationInfos, generatorStartupAdder, generatorStartup, reports); - boolean plannedOutageRateUpdated = addPlannedOutageRate(modificationInfos, generatorStartupAdder, generatorStartup, reports); - boolean forcedOutageRateUpdated = addForcedOutageRate(modificationInfos, generatorStartupAdder, generatorStartup, reports); + GeneratorStartup generatorStartup = generator.getExtension(GeneratorStartup.class); + boolean plannedActivePowerSetPointUpdated = addPlannedActivePowerSetPoint(plannedActivePowerSetPoint, + generatorStartupAdder, + generatorStartup, + reports); + boolean marginalCostUpdated = addMarginalCost(marginalCost, generatorStartupAdder, generatorStartup, reports); + boolean plannedOutageRateUpdated = addPlannedOutageRate(plannedOutageRate, generatorStartupAdder, generatorStartup, reports); + boolean forcedOutageRateUpdated = addForcedOutageRate(forcedOutageRate, generatorStartupAdder, generatorStartup, reports); if (plannedActivePowerSetPointUpdated || marginalCostUpdated || plannedOutageRateUpdated || forcedOutageRateUpdated) { generatorStartupAdder.add(); - ModificationUtils.getInstance().reportModifications(subReportNode, reports, "startUpAttributesModified", "Start up"); + if (subReportNode != null) { + ModificationUtils.getInstance().reportModifications(subReportNode, reports, "startUpAttributesModified", "Start up"); + } } } - private boolean addForcedOutageRate(GeneratorModificationInfos modificationInfos, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List reports) { + private static boolean addForcedOutageRate(AttributeModification forcedOutageRate, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List reports) { Double oldForcedOutageRate = generatorStartup != null ? generatorStartup.getForcedOutageRate() : Double.NaN; - if (modificationInfos.getForcedOutageRate() != null) { + if (forcedOutageRate != null) { generatorStartupAdder - .withForcedOutageRate(modificationInfos.getForcedOutageRate().getValue()); - reports.add(ModificationUtils.getInstance().buildModificationReport(oldForcedOutageRate, - modificationInfos.getForcedOutageRate().getValue(), - "Forced outage rate")); + .withForcedOutageRate(forcedOutageRate.getValue()); + if (reports != null) { + reports.add(ModificationUtils.getInstance().buildModificationReport(oldForcedOutageRate, + forcedOutageRate.getValue(), + "Forced outage rate")); + } return true; } else { generatorStartupAdder @@ -240,14 +271,16 @@ private boolean addForcedOutageRate(GeneratorModificationInfos modificationInfos return false; } - private boolean addPlannedOutageRate(GeneratorModificationInfos modificationInfos, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List reports) { + private static boolean addPlannedOutageRate(AttributeModification plannedOutageRate, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List reports) { Double oldPlannedOutageRate = generatorStartup != null ? generatorStartup.getPlannedOutageRate() : Double.NaN; - if (modificationInfos.getPlannedOutageRate() != null) { + if (plannedOutageRate != null) { generatorStartupAdder - .withPlannedOutageRate(modificationInfos.getPlannedOutageRate().getValue()); - reports.add(ModificationUtils.getInstance().buildModificationReport(oldPlannedOutageRate, - modificationInfos.getPlannedOutageRate().getValue(), - "Planning outage rate")); + .withPlannedOutageRate(plannedOutageRate.getValue()); + if (reports != null) { + reports.add(ModificationUtils.getInstance().buildModificationReport(oldPlannedOutageRate, + plannedOutageRate.getValue(), + "Planning outage rate")); + } return true; } else { generatorStartupAdder @@ -256,14 +289,16 @@ private boolean addPlannedOutageRate(GeneratorModificationInfos modificationInfo return false; } - private boolean addMarginalCost(GeneratorModificationInfos modificationInfos, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List reports) { + private static boolean addMarginalCost(AttributeModification marginalCost, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List reports) { Double oldMarginalCost = generatorStartup != null ? generatorStartup.getMarginalCost() : Double.NaN; - if (modificationInfos.getMarginalCost() != null) { + if (marginalCost != null) { generatorStartupAdder - .withMarginalCost(modificationInfos.getMarginalCost().getValue()); - reports.add(ModificationUtils.getInstance().buildModificationReport(oldMarginalCost, - modificationInfos.getMarginalCost().getValue(), - "Marginal cost")); + .withMarginalCost(marginalCost.getValue()); + if (reports != null) { + reports.add(ModificationUtils.getInstance().buildModificationReport(oldMarginalCost, + marginalCost.getValue(), + "Marginal cost")); + } return true; } else { generatorStartupAdder @@ -272,14 +307,17 @@ private boolean addMarginalCost(GeneratorModificationInfos modificationInfos, Ge return false; } - private boolean addPlannedActivePowerSetPoint(GeneratorModificationInfos modificationInfos, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List reports) { + private static boolean addPlannedActivePowerSetPoint(AttributeModification plannedActivePowerSetPoint, GeneratorStartupAdder generatorStartupAdder, + GeneratorStartup generatorStartup, List reports) { Double oldPlannedActivePowerSetPoint = generatorStartup != null ? generatorStartup.getPlannedActivePowerSetpoint() : Double.NaN; - if (modificationInfos.getPlannedActivePowerSetPoint() != null) { + if (plannedActivePowerSetPoint != null) { generatorStartupAdder - .withPlannedActivePowerSetpoint(modificationInfos.getPlannedActivePowerSetPoint().getValue()); - reports.add(ModificationUtils.getInstance().buildModificationReport(oldPlannedActivePowerSetPoint, - modificationInfos.getPlannedActivePowerSetPoint().getValue(), - "Planning active power set point")); + .withPlannedActivePowerSetpoint(plannedActivePowerSetPoint.getValue()); + if (reports != null) { + reports.add(ModificationUtils.getInstance().buildModificationReport(oldPlannedActivePowerSetPoint, + plannedActivePowerSetPoint.getValue(), + "Planning active power set point")); + } return true; } else { generatorStartupAdder @@ -339,15 +377,8 @@ private ReportNode modifyGeneratorVoltageRegulatorAttributes(GeneratorModificati Generator generator, ReportNode subReportNode, ReportNode subReportNodeSetpoints) { List voltageRegulationReports = new ArrayList<>(); - ReportNode reportVoltageSetpoint = null; - if (modificationInfos.getTargetV() != null) { - if (modificationInfos.getTargetV().getOp() == OperationType.SET) { - reportVoltageSetpoint = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetV, generator::getTargetV, - modificationInfos.getTargetV(), "Voltage"); - } else { - reportVoltageSetpoint = ModificationUtils.getInstance().buildModificationReport(generator.getTargetV(), Double.NaN, "Voltage"); - } - } + ReportNode reportVoltageSetpoint = modifyTargetV(generator, modificationInfos.getTargetV()); + ReportNode voltageRegulationOn = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setVoltageRegulatorOn, generator::isVoltageRegulatorOn, modificationInfos.getVoltageRegulationOn(), "VoltageRegulationOn"); if (voltageRegulationOn != null) { @@ -392,17 +423,24 @@ private ReportNode modifyGeneratorVoltageRegulatorAttributes(GeneratorModificati return subReportNodeSetpoints2; } - private void modifyGeneratorSetpointsAttributes(GeneratorModificationInfos modificationInfos, - Generator generator, ReportNode subReportNode) { - ReportNode reportActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetP, generator::getTargetP, modificationInfos.getTargetP(), "Active power"); - ReportNode reportReactivePower = null; - if (modificationInfos.getTargetQ() != null) { - if (modificationInfos.getTargetQ().getOp() == OperationType.SET) { - reportReactivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetQ, generator::getTargetQ, modificationInfos.getTargetQ(), "Reactive power"); + public static ReportNode modifyTargetV(Generator generator, AttributeModification modifTargetV) { + ReportNode reportVoltageSetpoint = null; + if (modifTargetV != null) { + if (modifTargetV.getOp() == OperationType.SET) { + reportVoltageSetpoint = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetV, generator::getTargetV, + modifTargetV, "Voltage"); } else { - reportReactivePower = ModificationUtils.getInstance().buildModificationReport(generator.getTargetQ(), Double.NaN, "Reactive power"); + reportVoltageSetpoint = ModificationUtils.getInstance().buildModificationReport(generator.getTargetV(), Double.NaN, "Voltage"); } } + return reportVoltageSetpoint; + } + + private void modifyGeneratorSetpointsAttributes(GeneratorModificationInfos modificationInfos, + Generator generator, ReportNode subReportNode) { + ReportNode reportActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetP, generator::getTargetP, modificationInfos.getTargetP(), "Active power"); + + ReportNode reportReactivePower = modifyTargetQ(generator, modificationInfos.getTargetQ()); ReportNode subReporterSetpoints = null; if (reportActivePower != null || reportReactivePower != null) { @@ -418,9 +456,25 @@ private void modifyGeneratorSetpointsAttributes(GeneratorModificationInfos modif modifyGeneratorActivePowerControlAttributes(modificationInfos, generator, subReportNode, subReporterSetpoints); } + public static ReportNode modifyTargetQ(Generator generator, AttributeModification modifTargetQ) { + ReportNode reportReactivePower = null; + if (modifTargetQ != null) { + if (modifTargetQ.getOp() == OperationType.SET) { + reportReactivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetQ, generator::getTargetQ, modifTargetQ, "Target reactive power"); + } else { + reportReactivePower = ModificationUtils.getInstance().buildModificationReport(generator.getTargetQ(), Double.NaN, "Target reactive power"); + } + } + return reportReactivePower; + } + private void modifyGeneratorLimitsAttributes(GeneratorModificationInfos modificationInfos, Generator generator, ReportNode subReportNode) { - ReportNode subReportNodeLimits = modifyGeneratorActiveLimitsAttributes(modificationInfos, generator, subReportNode); + ReportNode subReportNodeLimits = modifyGeneratorActiveLimitsAttributes(modificationInfos.getMaxP(), + modificationInfos.getMinP(), + modificationInfos.getRatedS(), + generator, + subReportNode); modifyGeneratorReactiveLimitsAttributes(modificationInfos, generator, subReportNode, subReportNodeLimits); } diff --git a/src/main/java/org/gridsuite/modification/server/modifications/LoadModification.java b/src/main/java/org/gridsuite/modification/server/modifications/LoadModification.java index 019271d8e..3bbbb68c8 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/LoadModification.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/LoadModification.java @@ -13,6 +13,7 @@ import com.powsybl.iidm.network.extensions.ConnectablePosition; import com.powsybl.iidm.network.extensions.ConnectablePositionAdder; import org.gridsuite.modification.server.NetworkModificationException; +import org.gridsuite.modification.server.dto.AttributeModification; import org.gridsuite.modification.server.dto.LoadModificationInfos; import static org.gridsuite.modification.server.NetworkModificationException.Type.LOAD_NOT_FOUND; @@ -53,13 +54,21 @@ private void modifyLoad(Load load, ReportNode subReportNode) { ModificationUtils.getInstance().applyElementaryModifications(load::setName, () -> load.getOptionalName().orElse("No value"), modificationInfos.getEquipmentName(), subReportNode, "Name"); ModificationUtils.getInstance().applyElementaryModifications(load::setLoadType, load::getLoadType, modificationInfos.getLoadType(), subReportNode, "Type"); - ModificationUtils.getInstance().applyElementaryModifications(load::setP0, load::getP0, modificationInfos.getP0(), subReportNode, "Constant active power"); - ModificationUtils.getInstance().applyElementaryModifications(load::setQ0, load::getQ0, modificationInfos.getQ0(), subReportNode, "Constant reactive power"); + modifyP0(load, modificationInfos.getP0(), subReportNode); + modifyQ0(load, modificationInfos.getQ0(), subReportNode); modifyLoadConnectivityAttributes(modificationInfos, load, subReportNode); // properties PropertiesUtils.applyProperties(load, subReportNode, modificationInfos.getProperties(), "LoadProperties"); } + public static void modifyQ0(Load load, AttributeModification q0, ReportNode subReportNode) { + ModificationUtils.getInstance().applyElementaryModifications(load::setQ0, load::getQ0, q0, subReportNode, "Constant reactive power"); + } + + public static void modifyP0(Load load, AttributeModification p0, ReportNode subReportNode) { + ModificationUtils.getInstance().applyElementaryModifications(load::setP0, load::getP0, p0, subReportNode, "Constant active power"); + } + private ReportNode modifyLoadConnectivityAttributes(LoadModificationInfos modificationInfos, Load load, ReportNode subReportNode) { ConnectablePosition connectablePosition = load.getExtension(ConnectablePosition.class); diff --git a/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java b/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java index 92d4e588a..c2b94e850 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java @@ -509,7 +509,9 @@ public void applyElementaryModifications(Consumer setter, Supplier get T newValue = modification.applyModification(oldValue); setter.accept(newValue); - insertReportNode(subReportNode, buildModificationReport(oldValue, newValue, fieldName)); + if (subReportNode != null) { + insertReportNode(subReportNode, buildModificationReport(oldValue, newValue, fieldName)); + } } } @@ -1073,12 +1075,16 @@ private void modifyExistingActivePowerControl(ActivePowerControl activePowerC Optional.ofNullable(participateInfo).ifPresent(info -> { activePowerControl.setParticipate(info.getValue()); - reports.add(buildModificationReport(oldParticipate, info.getValue(), "Participate")); + if (reports != null) { + reports.add(buildModificationReport(oldParticipate, info.getValue(), "Participate")); + } }); Optional.ofNullable(droopInfo).ifPresent(info -> { activePowerControl.setDroop(info.getValue()); - reports.add(buildModificationReport(oldDroop, info.getValue(), "Droop")); + if (reports != null) { + reports.add(buildModificationReport(oldDroop, info.getValue(), "Droop")); + } }); } @@ -1088,22 +1094,22 @@ private void createNewActivePowerControl(ActivePowerControlAdder adder, List reports) { boolean participate = participateInfo != null ? participateInfo.getValue() : false; adder.withParticipate(participate); - if (participateInfo != null) { + if (participateInfo != null && reports != null) { reports.add(buildModificationReport(null, participate, "Participate")); } double droop = droopInfo != null ? droopInfo.getValue() : Double.NaN; adder.withDroop(droop); - if (droopInfo != null) { + if (droopInfo != null && reports != null) { reports.add(buildModificationReport(Double.NaN, droop, "Droop")); } adder.add(); } public ReportNode modifyActivePowerControlAttributes(ActivePowerControl activePowerControl, - ActivePowerControlAdder activePowerControlAdder, - AttributeModification participateInfo, - AttributeModification droopInfo, - ReportNode subReportNode, + ActivePowerControlAdder activePowerControlAdder, + AttributeModification participateInfo, + AttributeModification droopInfo, + ReportNode subReportNode, ReportNode subReporterSetpoints) { List reports = new ArrayList<>(); if (activePowerControl != null) { @@ -1111,13 +1117,15 @@ public ReportNode modifyActivePowerControlAttributes(ActivePowerControl activ } else { createNewActivePowerControl(activePowerControlAdder, participateInfo, droopInfo, reports); } - - ReportNode subReportNodeSetpoints2 = subReporterSetpoints; - if (subReporterSetpoints == null && !reports.isEmpty()) { - subReportNodeSetpoints2 = subReportNode.newReportNode().withMessageTemplate(SETPOINTS, SETPOINTS).add(); + if (subReportNode != null) { + ReportNode subReportNodeSetpoints2 = subReporterSetpoints; + if (subReporterSetpoints == null && !reports.isEmpty()) { + subReportNodeSetpoints2 = subReportNode.newReportNode().withMessageTemplate(SETPOINTS, SETPOINTS).add(); + } + reportModifications(subReportNodeSetpoints2, reports, "activePowerRegulationModified", "Active power regulation"); + return subReportNodeSetpoints2; } - reportModifications(subReportNodeSetpoints2, reports, "activePowerRegulationModified", "Active power regulation"); - return subReportNodeSetpoints2; + return null; } public void checkMaxQGreaterThanMinQ( diff --git a/src/main/java/org/gridsuite/modification/server/modifications/ShuntCompensatorModification.java b/src/main/java/org/gridsuite/modification/server/modifications/ShuntCompensatorModification.java index 25aaebe37..899ace841 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/ShuntCompensatorModification.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/ShuntCompensatorModification.java @@ -13,6 +13,7 @@ import com.powsybl.iidm.network.extensions.ConnectablePosition; import com.powsybl.iidm.network.extensions.ConnectablePositionAdder; import org.gridsuite.modification.server.NetworkModificationException; +import org.gridsuite.modification.server.dto.AttributeModification; import org.gridsuite.modification.server.dto.ShuntCompensatorModificationInfos; import org.gridsuite.modification.server.dto.ShuntCompensatorType; @@ -81,21 +82,30 @@ public void apply(Network network, ReportNode subReportNode) { PropertiesUtils.applyProperties(shuntCompensator, subReportNode, modificationInfos.getProperties(), "ShuntCompensatorProperties"); } - private void modifyMaximumSectionCount(List reports, ShuntCompensator shuntCompensator, ShuntCompensatorLinearModel model) { - if (modificationInfos.getMaximumSectionCount() != null) { - var maximumSectionCount = modificationInfos.getMaximumSectionCount().getValue(); - if (modificationInfos.getMaxSusceptance() == null && modificationInfos.getMaxQAtNominalV() == null) { + public static void modifyMaximumSectionCount(AttributeModification maximumSectionCountModif, + AttributeModification maxSusceptance, + AttributeModification maxQAtNominalV, + List reports, + ShuntCompensator shuntCompensator, + ShuntCompensatorLinearModel model) { + if (maximumSectionCountModif != null) { + var maximumSectionCount = maximumSectionCountModif.getValue(); + if (maxSusceptance == null && maxQAtNominalV == null) { model.setBPerSection(model.getBPerSection() * shuntCompensator.getMaximumSectionCount() / maximumSectionCount); } - reports.add(ModificationUtils.getInstance().buildModificationReport(shuntCompensator.getMaximumSectionCount(), maximumSectionCount, "Maximum section count")); + if (reports != null) { + reports.add(ModificationUtils.getInstance().buildModificationReport(shuntCompensator.getMaximumSectionCount(), maximumSectionCount, "Maximum section count")); + } model.setMaximumSectionCount(maximumSectionCount); } } - private void modifySectionCount(List reports, ShuntCompensator shuntCompensator) { - if (modificationInfos.getSectionCount() != null) { - var newSectionCount = modificationInfos.getSectionCount().getValue(); - reports.add(ModificationUtils.getInstance().buildModificationReport(shuntCompensator.getSectionCount(), newSectionCount, "Section count")); + public static void modifySectionCount(AttributeModification sectionCount, List reports, ShuntCompensator shuntCompensator) { + if (sectionCount != null) { + var newSectionCount = sectionCount.getValue(); + if (reports != null) { + reports.add(ModificationUtils.getInstance().buildModificationReport(shuntCompensator.getSectionCount(), newSectionCount, "Section count")); + } shuntCompensator.setSectionCount(newSectionCount); } } @@ -106,7 +116,6 @@ private void applyModificationOnLinearModel(ReportNode subReportNode, ShuntCompe var shuntCompensatorType = model.getBPerSection() > 0 ? ShuntCompensatorType.CAPACITOR : ShuntCompensatorType.REACTOR; double oldSusceptancePerSection = model.getBPerSection(); double oldQAtNominalV = Math.abs(Math.pow(voltageLevel.getNominalV(), 2) * oldSusceptancePerSection); - double oldMaxSusceptance = oldSusceptancePerSection * shuntCompensator.getMaximumSectionCount(); double oldMaxQAtNominalV = oldQAtNominalV * shuntCompensator.getMaximumSectionCount(); double oldSwitchedOnSusceptance = oldSusceptancePerSection * shuntCompensator.getSectionCount(); double oldSwitchedOnQAtNominalV = oldQAtNominalV * shuntCompensator.getSectionCount(); @@ -118,11 +127,17 @@ private void applyModificationOnLinearModel(ReportNode subReportNode, ShuntCompe // 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(reports, shuntCompensator); - modifyMaximumSectionCount(reports, shuntCompensator, model); + modifySectionCount(modificationInfos.getSectionCount(), reports, shuntCompensator); + modifyMaximumSectionCount(modificationInfos.getMaximumSectionCount(), + modificationInfos.getMaxSusceptance(), + modificationInfos.getMaxQAtNominalV(), + reports, shuntCompensator, model); } else { - modifyMaximumSectionCount(reports, shuntCompensator, model); - modifySectionCount(reports, shuntCompensator); + modifyMaximumSectionCount(modificationInfos.getMaximumSectionCount(), + modificationInfos.getMaxSusceptance(), + modificationInfos.getMaxQAtNominalV(), + reports, shuntCompensator, model); + modifySectionCount(modificationInfos.getSectionCount(), reports, shuntCompensator); } int maximumSectionCount = modificationInfos.getMaximumSectionCount() != null ? modificationInfos.getMaximumSectionCount().getValue() : shuntCompensator.getMaximumSectionCount(); @@ -140,22 +155,10 @@ private void applyModificationOnLinearModel(ReportNode subReportNode, ShuntCompe } if (modificationInfos.getMaxQAtNominalV() != null) { - if (modificationInfos.getMaxQAtNominalV().getValue() < 0) { - throw new NetworkModificationException(NetworkModificationException.Type.MODIFY_SHUNT_COMPENSATOR_ERROR, - "Qmax at nominal voltage should be greater or equal to 0"); - } - double newQatNominalV = modificationInfos.getMaxQAtNominalV().getValue() / maximumSectionCount; - double newSusceptancePerSection = newQatNominalV / Math.pow(voltageLevel.getNominalV(), 2); - reports.add(ModificationUtils.getInstance().buildModificationReport(oldMaxQAtNominalV, modificationInfos.getMaxQAtNominalV().getValue(), "Qmax available at nominal voltage")); - - model.setBPerSection(shuntCompensatorType == ShuntCompensatorType.CAPACITOR ? newSusceptancePerSection : -newSusceptancePerSection); + modifyMaximumQAtNominalVoltage(modificationInfos.getMaxQAtNominalV(), voltageLevel, maximumSectionCount, reports, model, shuntCompensatorType); } - if (modificationInfos.getMaxSusceptance() != null) { - double newSusceptancePerSection = modificationInfos.getMaxSusceptance().getValue() / maximumSectionCount; - reports.add(ModificationUtils.getInstance().buildModificationReport(oldMaxSusceptance, modificationInfos.getMaxSusceptance().getValue(), "Maximal susceptance available")); - - model.setBPerSection(newSusceptancePerSection); + modifyMaxSusceptance(modificationInfos.getMaxSusceptance(), maximumSectionCount, reports, model); } reportSwitchedOnAndPerSectionValues(reports, oldQAtNominalV, oldSwitchedOnQAtNominalV, oldSusceptancePerSection, oldSwitchedOnSusceptance, oldMaxQAtNominalV, sectionCount, maximumSectionCount); @@ -163,6 +166,41 @@ private void applyModificationOnLinearModel(ReportNode subReportNode, ShuntCompe reports.forEach(report -> insertReportNode(subReportNode, report)); } + public static void modifyMaxSusceptance(AttributeModification maxSusceptance, + int maximumSectionCount, + List reports, + ShuntCompensatorLinearModel model) { + double newSusceptancePerSection = maxSusceptance.getValue() / maximumSectionCount; + if (reports != null) { + double oldSusceptancePerSection = model.getBPerSection(); + double oldMaxSusceptance = oldSusceptancePerSection * maximumSectionCount; + reports.add(ModificationUtils.getInstance().buildModificationReport(oldMaxSusceptance, maxSusceptance.getValue(), "Maximal susceptance available")); + } + model.setBPerSection(newSusceptancePerSection); + } + + public static void modifyMaximumQAtNominalVoltage(AttributeModification maxQAtNominalV, + VoltageLevel voltageLevel, + int maximumSectionCount, + List reports, + ShuntCompensatorLinearModel model, + ShuntCompensatorType shuntCompensatorType) { + if (maxQAtNominalV.getValue() < 0) { + throw new NetworkModificationException(NetworkModificationException.Type.MODIFY_SHUNT_COMPENSATOR_ERROR, + "Qmax at nominal voltage should be greater or equal to 0"); + } + double newQatNominalV = maxQAtNominalV.getValue() / maximumSectionCount; + double newSusceptancePerSection = newQatNominalV / Math.pow(voltageLevel.getNominalV(), 2); + if (reports != null) { + double oldSusceptancePerSection = model.getBPerSection(); + double oldQAtNominalV = Math.abs(Math.pow(voltageLevel.getNominalV(), 2) * oldSusceptancePerSection); + double oldMaxQAtNominalV = oldQAtNominalV * maximumSectionCount; + reports.add(ModificationUtils.getInstance().buildModificationReport(oldMaxQAtNominalV, maxQAtNominalV.getValue(), "Qmax available at nominal voltage")); + } + + model.setBPerSection(shuntCompensatorType == ShuntCompensatorType.CAPACITOR ? newSusceptancePerSection : -newSusceptancePerSection); + } + 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; diff --git a/src/main/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModification.java b/src/main/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModification.java index 4a940d4cc..5fee968aa 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModification.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModification.java @@ -26,6 +26,7 @@ public class TwoWindingsTransformerModification extends AbstractBranchModificati private static final String RATIO_TAP_CHANGER_SUBREPORTER_DEFAULT_MESSAGE = "Ratio tap changer"; private static final String PHASE_TAP_CHANGER_SUBREPORTER_DEFAULT_MESSAGE = "Phase tap changer"; + public static final String MAGNETIZING_CONDUCTANCE_FIELD_NAME = "Magnetizing conductance"; public TwoWindingsTransformerModification(TwoWindingsTransformerModificationInfos modificationInfos) { super(modificationInfos); @@ -58,49 +59,111 @@ protected void modifyCharacteristics(Branch branch, BranchModificationInfos b ReportNode characteristicsReporter = subReportNode.newReportNode().withMessageTemplate("characteristics", "Characteristics").add(); // Branch specific fields - if (branchModificationInfos.getR() != null && branchModificationInfos.getR().getValue() != null) { - insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(twoWindingsTransformer.getR(), - branchModificationInfos.getR().getValue(), "Series resistance", 1)); - twoWindingsTransformer.setR(branchModificationInfos.getR().getValue()); - } - if (branchModificationInfos.getX() != null && branchModificationInfos.getX().getValue() != null) { - insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(twoWindingsTransformer.getX(), - branchModificationInfos.getX().getValue(), "Series reactance", 1)); - twoWindingsTransformer.setX(branchModificationInfos.getX().getValue()); - } + modifyR(twoWindingsTransformer, branchModificationInfos.getR(), characteristicsReporter); + modifyX(twoWindingsTransformer, branchModificationInfos.getX(), characteristicsReporter); // Transformer specific fields TwoWindingsTransformerModificationInfos twoWindingsTransformerModificationInfos = (TwoWindingsTransformerModificationInfos) branchModificationInfos; - if (twoWindingsTransformerModificationInfos.getG() != null && twoWindingsTransformerModificationInfos.getG().getValue() != null) { - // convert reported value from siemens to microsiemens - double oldMagnetizingConductanceToReport = twoWindingsTransformer.getG() * Math.pow(10, 6); - double newMagnetizingConductanceToReport = twoWindingsTransformerModificationInfos.getG().getValue() * Math.pow(10, 6); - insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(oldMagnetizingConductanceToReport, - newMagnetizingConductanceToReport, "Magnetizing conductance", 1)); - twoWindingsTransformer.setG(twoWindingsTransformerModificationInfos.getG().getValue()); + modifyTransformerFields(twoWindingsTransformer, + twoWindingsTransformerModificationInfos.getG(), + twoWindingsTransformerModificationInfos.getB(), + twoWindingsTransformerModificationInfos.getRatedS(), + twoWindingsTransformerModificationInfos.getRatedU1(), + twoWindingsTransformerModificationInfos.getRatedU2(), + characteristicsReporter); + } + + public static void modifyTransformerFields(TwoWindingsTransformer transformer, + AttributeModification modifG, + AttributeModification modifB, + AttributeModification modifRatedS, + AttributeModification modifRatedU1, + AttributeModification modifRatedU2, + ReportNode reportNode) { + modifyG(transformer, modifG, reportNode); + modifyB(transformer, modifB, reportNode); + modifyRatedS(transformer, modifRatedS, reportNode); + modifyRatedU1(transformer, modifRatedU1, reportNode); + modifyRatedU2(transformer, modifRatedU2, reportNode); + } + + public static void modifyRatedU2(TwoWindingsTransformer transformer, AttributeModification modifRatedU2, ReportNode reportNode) { + if (modifRatedU2 != null && modifRatedU2.getValue() != null) { + if (reportNode != null) { + insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(transformer.getRatedU2(), + modifRatedU2.getValue(), "Rated Voltage (Side 2)", 1)); + } + transformer.setRatedU2(modifRatedU2.getValue()); } - if (twoWindingsTransformerModificationInfos.getB() != null && twoWindingsTransformerModificationInfos.getB().getValue() != null) { + } + + public static void modifyRatedU1(TwoWindingsTransformer transformer, AttributeModification modifRatedU1, ReportNode reportNode) { + if (modifRatedU1 != null && modifRatedU1.getValue() != null) { + if (reportNode != null) { + insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(transformer.getRatedU1(), + modifRatedU1.getValue(), "Rated Voltage (Side 1)", 1)); + } + transformer.setRatedU1(modifRatedU1.getValue()); + } + } + + public static void modifyRatedS(TwoWindingsTransformer transformer, AttributeModification modifRatedS, ReportNode reportNode) { + if (modifRatedS != null && modifRatedS.getValue() != null) { + if (reportNode != null) { + insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(transformer.getRatedS(), + modifRatedS.getValue(), "Rated nominal power", 1)); + } + transformer.setRatedS(modifRatedS.getValue()); + } + } + + public static void modifyB(TwoWindingsTransformer transformer, AttributeModification modifB, ReportNode reportNode) { + if (modifB != null && modifB.getValue() != null) { // convert reported value from siemens to microsiemens - double oldMagnetizingSusceptanceToReport = twoWindingsTransformer.getB() * Math.pow(10, 6); - double newMagnetizingSusceptanceToReport = twoWindingsTransformerModificationInfos.getB().getValue() * Math.pow(10, 6); - insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(oldMagnetizingSusceptanceToReport, - newMagnetizingSusceptanceToReport, "Magnetizing susceptance", 1)); - twoWindingsTransformer.setB(twoWindingsTransformerModificationInfos.getB().getValue()); + if (reportNode != null) { + double oldMagnetizingSusceptanceToReport = transformer.getB() * Math.pow(10, 6); + double newMagnetizingSusceptanceToReport = modifB.getValue() * Math.pow(10, 6); + insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(oldMagnetizingSusceptanceToReport, + newMagnetizingSusceptanceToReport, "Magnetizing susceptance", 1)); + } + transformer.setB(modifB.getValue()); } - if (twoWindingsTransformerModificationInfos.getRatedS() != null && twoWindingsTransformerModificationInfos.getRatedS().getValue() != null) { - insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(twoWindingsTransformer.getRatedS(), - twoWindingsTransformerModificationInfos.getRatedS().getValue(), "Rated nominal power", 1)); - twoWindingsTransformer.setRatedS(twoWindingsTransformerModificationInfos.getRatedS().getValue()); + } + + public static void modifyG(TwoWindingsTransformer transformer, AttributeModification modifG, ReportNode reportNode) { + if (modifG != null && modifG.getValue() != null) { + // convert reported value from siemens to microsiemens + if (reportNode != null) { + double oldMagnetizingConductanceToReport = transformer.getG() * Math.pow(10, 6); + double newMagnetizingConductanceToReport = modifG.getValue() * Math.pow(10, 6); + ReportNode gReportNode = ModificationUtils.getInstance().buildModificationReport( + oldMagnetizingConductanceToReport, + newMagnetizingConductanceToReport, + MAGNETIZING_CONDUCTANCE_FIELD_NAME, + 1); + insertReportNode(reportNode, gReportNode); + } + transformer.setG(modifG.getValue()); } - if (twoWindingsTransformerModificationInfos.getRatedU1() != null && twoWindingsTransformerModificationInfos.getRatedU1().getValue() != null) { - insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(twoWindingsTransformer.getRatedU1(), - twoWindingsTransformerModificationInfos.getRatedU1().getValue(), "Rated Voltage (Side 1)", 1)); - twoWindingsTransformer.setRatedU1(twoWindingsTransformerModificationInfos.getRatedU1().getValue()); + } + + public static void modifyX(TwoWindingsTransformer twt, AttributeModification modifX, ReportNode reportNode) { + if (modifX != null && modifX.getValue() != null) { + if (reportNode != null) { + insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(twt.getX(), + modifX.getValue(), "Series reactance", 1)); + } + twt.setX(modifX.getValue()); } - if (twoWindingsTransformerModificationInfos.getRatedU2() != null && twoWindingsTransformerModificationInfos.getRatedU2().getValue() != null) { - insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(twoWindingsTransformer.getRatedU2(), - twoWindingsTransformerModificationInfos.getRatedU2().getValue(), "Rated Voltage (Side 2)", 1)); - twoWindingsTransformer.setRatedU2(twoWindingsTransformerModificationInfos.getRatedU2().getValue()); + } + + public static void modifyR(TwoWindingsTransformer twt, AttributeModification modifR, ReportNode reportNode) { + if (modifR != null && modifR.getValue() != null) { + if (reportNode != null) { + insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(twt.getR(), + modifR.getValue(), "Series resistance", 1)); + } + twt.setR(modifR.getValue()); } } @@ -152,8 +215,8 @@ private void processPhaseTapChanger(Network network, regulationMode = phaseTapChangerInfos.getRegulationMode().getValue(); } if (!PhaseTapChanger.RegulationMode.FIXED_TAP.equals(regulationMode)) { - processPhaseTapRegulation(phaseTapChangerInfos, phaseTapChanger, phaseTapChangerAdder, regulationReports, - regulationMode, isModification); + processPhaseTapRegulation(phaseTapChanger, phaseTapChangerAdder, regulationMode, isModification, phaseTapChangerInfos.getRegulationValue(), phaseTapChangerInfos.getTargetDeadband(), regulationReports + ); } processRegulatingTerminal(phaseTapChangerInfos, phaseTapChanger, phaseTapChangerAdder, regulationReports, @@ -161,8 +224,7 @@ private void processPhaseTapChanger(Network network, twt, isModification); List positionsAndStepsReports = new ArrayList<>(); - processTapChangerPositionsAndSteps(phaseTapChangerInfos, phaseTapChanger, phaseTapChangerAdder, positionsAndStepsReports, - isModification); + processTapChangerPositionsAndSteps(phaseTapChanger, phaseTapChangerAdder, isModification, phaseTapChangerInfos.getLowTapPosition(), phaseTapChangerInfos.getTapPosition(), phaseTapChangerInfos.getSteps(), positionsAndStepsReports); if (!isModification) { phaseTapChangerAdder.add(); @@ -186,33 +248,36 @@ private void processPhaseTapChanger(Network network, } } - private void processPhaseTapRegulation(PhaseTapChangerModificationInfos phaseTapChangerInfos, - PhaseTapChanger phaseTapChanger, - PhaseTapChangerAdder phaseTapChangerAdder, - List regulationReports, - PhaseTapChanger.RegulationMode regulationMode, - boolean isModification) { + public static void processPhaseTapRegulation(PhaseTapChanger phaseTapChanger, + PhaseTapChangerAdder phaseTapChangerAdder, + PhaseTapChanger.RegulationMode regulationMode, + boolean isModification, + AttributeModification modifyRegulationValue, + AttributeModification modifyTargetDeadband, + List regulationReports) { if (regulationMode != null) { - ReportNode regulationReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( + String fieldName = (regulationMode.equals(PhaseTapChanger.RegulationMode.CURRENT_LIMITER)) ? "Value" : "Flow set point"; + ReportNode regulationValueReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( isModification ? phaseTapChanger::setRegulationValue : phaseTapChangerAdder::setRegulationValue, isModification ? phaseTapChanger::getRegulationValue : () -> null, - phaseTapChangerInfos.getRegulationValue(), - regulationMode.equals(PhaseTapChanger.RegulationMode.CURRENT_LIMITER) ? "Value" : "Flow set point", + modifyRegulationValue, + fieldName, 2); - if (regulationReport != null) { - regulationReports.add(regulationReport); + if (regulationReports != null && regulationValueReportNode != null) { + regulationReports.add(regulationValueReportNode); } } - ReportNode targetDeadbandReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( + ReportNode targetDeadbandReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( isModification ? phaseTapChanger::setTargetDeadband : phaseTapChangerAdder::setTargetDeadband, isModification ? phaseTapChanger::getTargetDeadband : () -> null, - phaseTapChangerInfos.getTargetDeadband(), "Target deadband", 2); - if (targetDeadbandReport != null) { - regulationReports.add(targetDeadbandReport); + modifyTargetDeadband, "Target deadband", 2); + + if (regulationReports != null && targetDeadbandReportNode != null) { + regulationReports.add(targetDeadbandReportNode); } if (isModification) { @@ -246,8 +311,8 @@ private void processRatioTapChanger(Network network, processRatioVoltageRegulation(ratioTapChangerInfos, twt, ratioTapChanger, ratioTapChangerAdder, voltageRegulationReports, network, isModification); List positionsAndStepsReports = new ArrayList<>(); - processTapChangerPositionsAndSteps(ratioTapChangerInfos, ratioTapChanger, ratioTapChangerAdder, positionsAndStepsReports, - isModification); + processTapChangerPositionsAndSteps(ratioTapChanger, ratioTapChangerAdder, isModification, ratioTapChangerInfos.getLowTapPosition(), ratioTapChangerInfos.getTapPosition(), ratioTapChangerInfos.getSteps(), positionsAndStepsReports + ); if (!isModification) { ratioTapChangerAdder.add(); @@ -292,27 +357,33 @@ private void processRatioVoltageRegulation(RatioTapChangerModificationInfos rati List voltageRegulationReports, Network network, boolean isModification) { + modifyTargets(ratioTapChanger, ratioTapChangerAdder, isModification, ratioTapChangerInfos.getTargetV(), ratioTapChangerInfos.getTargetDeadband(), voltageRegulationReports); - ReportNode targetVoltageReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( - isModification ? ratioTapChanger::setTargetV - : ratioTapChangerAdder::setTargetV, - isModification ? ratioTapChanger::getTargetV : () -> null, - ratioTapChangerInfos.getTargetV(), "Target voltage", 2); - if (targetVoltageReport != null) { - voltageRegulationReports.add(targetVoltageReport); - } + processRegulatingTerminal(ratioTapChangerInfos, ratioTapChanger, ratioTapChangerAdder, voltageRegulationReports, + network, twt, isModification); + } + + public static void modifyTargets(RatioTapChanger ratioTapChanger, RatioTapChangerAdder ratioTapChangerAdder, boolean isModification, AttributeModification targetV, AttributeModification targetDeadband, List voltageRegulationReports) { + ReportNode targetVoltageReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( + isModification ? ratioTapChanger::setTargetV + : ratioTapChangerAdder::setTargetV, + isModification ? ratioTapChanger::getTargetV : () -> null, + targetV, "Target voltage", 2); - ReportNode targetDeadbandReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( + ReportNode targetDeadbandReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( isModification ? ratioTapChanger::setTargetDeadband : ratioTapChangerAdder::setTargetDeadband, isModification ? ratioTapChanger::getTargetDeadband : () -> null, - ratioTapChangerInfos.getTargetDeadband(), "Target deadband", 2); - if (targetDeadbandReport != null) { - voltageRegulationReports.add(targetDeadbandReport); - } + targetDeadband, "Target deadband", 2); - processRegulatingTerminal(ratioTapChangerInfos, ratioTapChanger, ratioTapChangerAdder, voltageRegulationReports, - network, twt, isModification); + if (voltageRegulationReports != null) { + if (targetVoltageReportNode != null) { + voltageRegulationReports.add(targetVoltageReportNode); + } + if (targetDeadbandReportNode != null) { + voltageRegulationReports.add(targetDeadbandReportNode); + } + } } private void processRegulatingTerminal(TapChangerModificationInfos tapChangerModificationInfos, @@ -369,35 +440,25 @@ private void setRegulatingTerminalInfos(TapChangerModificationInfos tapChangerMo tapChangerModificationInfos.setRegulatingTerminalType(new AttributeModification<>(terminal.getConnectable().getType().name(), OperationType.SET)); } - private void processTapchangerSteps(List tapChangerStepsReports, - TapChangerModificationInfos tapChangerModificationInfos, - TapChangerAdder tapChangerAdder, - TapChangerStepsReplacer tapChangerStepReplacer, - boolean isModification) { - tapChangerStepsReports.add(ReportNode.newRootReportNode() - .withMessageTemplate("tapChangerStepsModification", " Taps were replaced by new ones below") - .withSeverity(TypedValue.INFO_SEVERITY) - .build()); - for (TapChangerStepCreationInfos step : tapChangerModificationInfos.getSteps()) { - addStepAttributeReports(tapChangerStepsReports, step); + private static void processTapchangerSteps(List tapChangerStepsReports, + TapChangerAdder tapChangerAdder, + TapChangerStepsReplacer tapChangerStepReplacer, + boolean isModification, + List modifSteps) { + if (tapChangerStepsReports != null) { + tapChangerStepsReports.add(ReportNode.newRootReportNode() + .withMessageTemplate("tapChangerStepsModification", " Taps were replaced by new ones below") + .withSeverity(TypedValue.INFO_SEVERITY) + .build()); + } + for (TapChangerStepCreationInfos step : modifSteps) { + if (tapChangerStepsReports != null) { + addStepAttributeReports(tapChangerStepsReports, step); + } if (tapChangerStepReplacer instanceof RatioTapChangerStepsReplacer || tapChangerAdder instanceof RatioTapChangerAdder) { - if (isModification) { - tapChangerStepReplacer.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG()) - .setB(step.getB()).setRho(step.getRho()).endStep(); - } else { - tapChangerAdder.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG()) - .setB(step.getB()).setRho(step.getRho()).endStep(); - } + processRatioTapChangerStep(tapChangerAdder, tapChangerStepReplacer, isModification, step); } else { - addStepAttributeReport(tapChangerStepsReports, "newStepAlpha" + step.getAlpha(), - " Shift angle : ${alpha}", "alpha", String.valueOf(step.getAlpha())); - if (isModification) { - ((PhaseTapChangerStepsReplacer) tapChangerStepReplacer).beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG()) - .setB(step.getB()).setRho(step.getRho()).setAlpha(step.getAlpha()).endStep(); - } else { - ((PhaseTapChangerAdder) tapChangerAdder).beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG()) - .setB(step.getB()).setRho(step.getRho()).setAlpha(step.getAlpha()).endStep(); - } + processPhaseTapChangerStep(tapChangerStepsReports, (PhaseTapChangerAdder) tapChangerAdder, (PhaseTapChangerStepsReplacer) tapChangerStepReplacer, isModification, step); } } if (isModification) { @@ -405,7 +466,31 @@ private void processTapchangerSteps(List tapChangerStepsReports, } } - private void addStepAttributeReports(List tapChangerStepsReports, TapChangerStepCreationInfos step) { + private static void processPhaseTapChangerStep(List tapChangerStepsReports, PhaseTapChangerAdder tapChangerAdder, PhaseTapChangerStepsReplacer tapChangerStepReplacer, boolean isModification, TapChangerStepCreationInfos step) { + if (tapChangerStepsReports != null) { + addStepAttributeReport(tapChangerStepsReports, "newStepAlpha" + step.getAlpha(), + " Shift angle : ${alpha}", "alpha", String.valueOf(step.getAlpha())); + } + if (isModification) { + tapChangerStepReplacer.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG()) + .setB(step.getB()).setRho(step.getRho()).setAlpha(step.getAlpha()).endStep(); + } else { + tapChangerAdder.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG()) + .setB(step.getB()).setRho(step.getRho()).setAlpha(step.getAlpha()).endStep(); + } + } + + private static void processRatioTapChangerStep(TapChangerAdder tapChangerAdder, TapChangerStepsReplacer tapChangerStepReplacer, boolean isModification, TapChangerStepCreationInfos step) { + if (isModification) { + tapChangerStepReplacer.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG()) + .setB(step.getB()).setRho(step.getRho()).endStep(); + } else { + tapChangerAdder.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG()) + .setB(step.getB()).setRho(step.getRho()).endStep(); + } + } + + private static void addStepAttributeReports(List tapChangerStepsReports, TapChangerStepCreationInfos step) { addStepAttributeReport(tapChangerStepsReports, "newStepIndex" + step.getIndex(), " Tap (${index})", "index", String.valueOf(step.getIndex())); addStepAttributeReport(tapChangerStepsReports, "newStepResistance" + step.getR(), @@ -420,41 +505,48 @@ private void addStepAttributeReports(List tapChangerStepsReports, Ta " Ratio : ${rho}", "rho", String.valueOf(step.getRho())); } - private void processTapChangerPositionsAndSteps(TapChangerModificationInfos tapChangerModificationInfos, - TapChanger tapChanger, - TapChangerAdder tapChangerAdder, - List tapChangerReports, - boolean isModification) { - ReportNode lowTapPositionReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( + public static void processTapChangerPositionsAndSteps(TapChanger tapChanger, + TapChangerAdder tapChangerAdder, + boolean isModification, + AttributeModification modifyLowTapPosition, + AttributeModification modifyTapPosition, + List modifySteps, + List tapChangerReports) { + ReportNode lowTapPositionReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( isModification ? tapChanger::setLowTapPosition : tapChangerAdder::setLowTapPosition, isModification ? tapChanger::getLowTapPosition : () -> null, - tapChangerModificationInfos.getLowTapPosition(), "Low tap position", 2); - if (lowTapPositionReport != null) { - tapChangerReports.add(lowTapPositionReport); - } + modifyLowTapPosition, "Low tap position", 2); - ReportNode tapPositionReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( + ReportNode tapPositionReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport( isModification ? tapChanger::setTapPosition : tapChangerAdder::setTapPosition, isModification ? tapChanger::getTapPosition : () -> null, - tapChangerModificationInfos.getTapPosition(), "Tap position", 2); - if (tapPositionReport != null) { - tapChangerReports.add(tapPositionReport); + modifyTapPosition, "Tap position", 2); + + if (tapChangerReports != null) { + if (lowTapPositionReportNode != null) { + tapChangerReports.add(lowTapPositionReportNode); + } + if (tapPositionReportNode != null) { + tapChangerReports.add(tapPositionReportNode); + } } // Add steps - if (tapChangerModificationInfos.getSteps() != null) { - tapChangerReports.add(ReportNode.newRootReportNode() - .withMessageTemplate("tapsModification", " Taps") - .withSeverity(TypedValue.INFO_SEVERITY) - .build()); - processTapchangerSteps(tapChangerReports, tapChangerModificationInfos, - tapChangerAdder, isModification ? tapChanger.stepsReplacer() : null, isModification); + if (modifySteps != null) { + if (tapChangerReports != null) { + tapChangerReports.add(ReportNode.newRootReportNode() + .withMessageTemplate("tapsModification", " Taps") + .withSeverity(TypedValue.INFO_SEVERITY) + .build()); + } + processTapchangerSteps(tapChangerReports, + tapChangerAdder, isModification ? tapChanger.stepsReplacer() : null, isModification, modifySteps); } } - private void addStepAttributeReport(List tapChangerStepsReports, String key, String defaultMessage, + private static void addStepAttributeReport(List tapChangerStepsReports, String key, String defaultMessage, String valueKey, String value) { tapChangerStepsReports.add(ReportNode.newRootReportNode() .withMessageTemplate(key, defaultMessage) diff --git a/src/main/java/org/gridsuite/modification/server/modifications/VoltageLevelModification.java b/src/main/java/org/gridsuite/modification/server/modifications/VoltageLevelModification.java index 7bbd83e8b..0fb9eebc3 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/VoltageLevelModification.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/VoltageLevelModification.java @@ -13,7 +13,9 @@ import com.powsybl.iidm.network.extensions.IdentifiableShortCircuit; import com.powsybl.iidm.network.extensions.IdentifiableShortCircuitAdder; import org.gridsuite.modification.server.NetworkModificationException; +import org.gridsuite.modification.server.dto.AttributeModification; import org.gridsuite.modification.server.dto.VoltageLevelModificationInfos; + import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -84,52 +86,79 @@ public void apply(Network network, ReportNode subReportNode) { .add(); ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setName, () -> voltageLevel.getOptionalName().orElse("No value"), modificationInfos.getEquipmentName(), subReportNode, "Name"); - ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setNominalV, voltageLevel::getNominalV, modificationInfos.getNominalV(), subReportNode, "Nominal voltage"); - ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setLowVoltageLimit, voltageLevel::getLowVoltageLimit, modificationInfos.getLowVoltageLimit(), subReportNode, "Low voltage limit"); - ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setHighVoltageLimit, voltageLevel::getHighVoltageLimit, modificationInfos.getHighVoltageLimit(), subReportNode, "High voltage limit"); + modifyNominalV(voltageLevel, modificationInfos.getNominalV(), subReportNode); + modifLowVoltageLimit(voltageLevel, modificationInfos.getLowVoltageLimit(), subReportNode); + modifyHighVoltageLimit(voltageLevel, modificationInfos.getHighVoltageLimit(), subReportNode); - modifyVoltageLevelShortCircuit(subReportNode, voltageLevel); + modifyVoltageLevelShortCircuit(modificationInfos.getIpMin(), modificationInfos.getIpMax(), subReportNode, voltageLevel); PropertiesUtils.applyProperties(voltageLevel, subReportNode, modificationInfos.getProperties(), "VlProperties"); } - private void modifyVoltageLevelShortCircuit(ReportNode subReportNode, VoltageLevel voltageLevel) { - if (modificationInfos.getIpMin() != null || modificationInfos.getIpMax() != null) { - List reports = new ArrayList<>(); - IdentifiableShortCircuit identifiableShortCircuit = voltageLevel.getExtension(IdentifiableShortCircuit.class); - IdentifiableShortCircuitAdder identifiableShortCircuitAdder = voltageLevel.newExtension(IdentifiableShortCircuitAdder.class); - var oldIpMin = identifiableShortCircuit == null ? null : identifiableShortCircuit.getIpMin(); - var oldIpMax = identifiableShortCircuit == null ? null : identifiableShortCircuit.getIpMax(); + public static void modifyHighVoltageLimit(VoltageLevel voltageLevel, AttributeModification highVoltageLimit, ReportNode subReportNode) { + ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setHighVoltageLimit, voltageLevel::getHighVoltageLimit, highVoltageLimit, subReportNode, "High voltage limit"); + } - if (modificationInfos.getIpMin() != null) { - var newIpMin = modificationInfos.getIpMin().getValue(); + public static void modifLowVoltageLimit(VoltageLevel voltageLevel, AttributeModification lowVoltageLimit, ReportNode subReportNode) { + ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setLowVoltageLimit, voltageLevel::getLowVoltageLimit, lowVoltageLimit, subReportNode, "Low voltage limit"); + } - identifiableShortCircuitAdder.withIpMin(newIpMin); + public static void modifyNominalV(VoltageLevel voltageLevel, AttributeModification modifNominalV, ReportNode subReportNode) { + ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setNominalV, voltageLevel::getNominalV, modifNominalV, subReportNode, "Nominal voltage"); + } - //convert to kA to report it like the user set it. - var oldIpMinToReport = oldIpMin != null ? oldIpMin * 0.001 : null; - var newIpMinToReport = newIpMin * 0.001; + public static void modifyVoltageLevelShortCircuit(AttributeModification ipMin, + AttributeModification ipMax, + ReportNode subReportNode, + VoltageLevel voltageLevel) { + if (ipMin == null && ipMax == null) { + return; + } - reports.add(ModificationUtils.getInstance() - .buildModificationReport(oldIpMinToReport, newIpMinToReport, "Low short circuit current limit")); - } else if (oldIpMin != null) { - identifiableShortCircuitAdder.withIpMin(oldIpMin); - } + List reports = new ArrayList<>(); + IdentifiableShortCircuitAdder identifiableShortCircuitAdder = voltageLevel.newExtension(IdentifiableShortCircuitAdder.class); + Double oldIpMin = null; + Double oldIpMax = null; + IdentifiableShortCircuit identifiableShortCircuit = voltageLevel.getExtension(IdentifiableShortCircuit.class); + if (identifiableShortCircuit != null) { + oldIpMin = identifiableShortCircuit.getIpMin(); + oldIpMax = identifiableShortCircuit.getIpMax(); + } - if (modificationInfos.getIpMax() != null) { - var newIpMax = modificationInfos.getIpMax().getValue(); - identifiableShortCircuitAdder.withIpMax(newIpMax); - - //Convert to kA to report it like the user set it. - var oldIpMaxToReport = oldIpMax != null ? oldIpMax * 0.001 : null; - var newIpMaxToReport = newIpMax * 0.001; - reports.add(ModificationUtils.getInstance() - .buildModificationReport(oldIpMaxToReport, newIpMaxToReport, "High short circuit current limit")); - } else if (oldIpMax != null) { - identifiableShortCircuitAdder.withIpMax(oldIpMax); - } + if (ipMin != null) { + var newIpMin = ipMin.getValue(); - identifiableShortCircuitAdder.add(); + identifiableShortCircuitAdder.withIpMin(newIpMin); + + //convert to kA to report it like the user set it. + var oldIpMinToReport = convertToKiloAmps(oldIpMin); + var newIpMinToReport = convertToKiloAmps(newIpMin); + reports.add(ModificationUtils.getInstance() + .buildModificationReport(oldIpMinToReport, newIpMinToReport, "Low short circuit current limit")); + } else if (oldIpMin != null) { + identifiableShortCircuitAdder.withIpMin(oldIpMin); + } + + if (ipMax != null) { + var newIpMax = ipMax.getValue(); + identifiableShortCircuitAdder.withIpMax(newIpMax); + + //Convert to kA to report it like the user set it. + var oldIpMaxToReport = convertToKiloAmps(oldIpMax); + var newIpMaxToReport = convertToKiloAmps(newIpMax); + reports.add(ModificationUtils.getInstance() + .buildModificationReport(oldIpMaxToReport, newIpMaxToReport, "High short circuit current limit")); + } else if (oldIpMax != null) { + identifiableShortCircuitAdder.withIpMax(oldIpMax); + } + + identifiableShortCircuitAdder.add(); + if (subReportNode != null) { reports.forEach(report -> insertReportNode(subReportNode, report)); } } + + private static Double convertToKiloAmps(Double value) { + return (value != null) ? value * 0.001 : null; + } } + diff --git a/src/test/java/org/gridsuite/modification/server/modifications/GeneratorByFormulaModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/GeneratorByFormulaModificationTest.java index 9c3a4d38a..ae5b98b1b 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/GeneratorByFormulaModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/GeneratorByFormulaModificationTest.java @@ -299,7 +299,7 @@ protected void assertAfterNetworkModificationCreation() { assertNotNull(generatorStartup1); assertEquals(50, generator1.getTargetP(), 0); assertEquals(15, generatorStartup1.getMarginalCost(), 0); - assertEquals(55, generatorStartup1.getPlannedOutageRate(), 0); + assertEquals(2.5, generatorStartup1.getPlannedOutageRate(), 0); assertEquals(1100, generatorStartup1.getForcedOutageRate(), 0); assertEquals(50, generatorStartup1.getPlannedActivePowerSetpoint(), 0); assertEquals(502, generator1.getMaxP(), 0); @@ -310,7 +310,7 @@ protected void assertAfterNetworkModificationCreation() { assertNotNull(generatorStartup2); assertEquals(100, generator2.getTargetP(), 0); assertEquals(15, generatorStartup2.getMarginalCost(), 0); - assertEquals(55, generatorStartup2.getPlannedOutageRate(), 0); + assertEquals(2.5, generatorStartup2.getPlannedOutageRate(), 0); assertEquals(1100, generatorStartup2.getForcedOutageRate(), 0); assertEquals(50, generatorStartup2.getPlannedActivePowerSetpoint(), 0); assertEquals(2002, generator2.getMaxP(), 0); From b3c9198e30b1a17527263bf3efd2111e995d7f32 Mon Sep 17 00:00:00 2001 From: Antoine Bouhours Date: Thu, 26 Sep 2024 14:54:40 +0200 Subject: [PATCH 2/6] update to gridsuite-dependencies 34 (#538) Signed-off-by: BOUHOURS Antoine --- pom.xml | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index 1fe15bdac..d4631d1fe 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ - 33 + 34 1.0.5 0.0.2 1.16.2 @@ -116,8 +116,6 @@ org.gridsuite gridsuite-filter - - 1.0.13 com.powsybl @@ -130,20 +128,6 @@ com.powsybl powsybl-network-store-client - - 1.17.1 - - - - com.powsybl - powsybl-network-store-iidm-impl - 1.17.1 - - - - com.powsybl - powsybl-network-store-model - 1.17.1 com.powsybl From 977b4d1db15ed9060283e645a922f37dde8e75fb Mon Sep 17 00:00:00 2001 From: Ayoub LABIDI <117761394+ayolab@users.noreply.github.com> Date: Thu, 26 Sep 2024 15:07:19 +0200 Subject: [PATCH 3/6] Remove hack and update report management (#531) Signed-off-by: Ayoub LABIDI --- .../server/NetworkModificationController.java | 12 ++--- .../modification/server/dto/BuildInfos.java | 4 +- .../modification/server/dto/ReportInfos.java | 2 +- .../NetworkModificationApplicator.java | 18 ++++---- .../service/NetworkModificationService.java | 6 +-- .../server/ModificationControllerTest.java | 2 +- .../server/VoltageInitReportTest.java | 2 +- .../CompositeModificationsTest.java | 25 ++++++----- .../server/service/BuildTest.java | 45 +++++++------------ .../reports_voltage_init_modification_ok.json | 4 +- ...ts_voltage_init_modification_warnings.json | 4 +- 11 files changed, 55 insertions(+), 69 deletions(-) diff --git a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java index 7742c6811..ac91b8ab0 100644 --- a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java +++ b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java @@ -90,16 +90,16 @@ public ResponseEntity> handleNetworkModifica @RequestBody List modificationsUuidList) { switch (action) { case COPY: - return ResponseEntity.ok().body(networkModificationService.duplicateModifications(targetGroupUuid, networkUuid, variantId, new ReportInfos(reportUuid, reporterId.toString()), modificationsUuidList)); + return ResponseEntity.ok().body(networkModificationService.duplicateModifications(targetGroupUuid, networkUuid, variantId, new ReportInfos(reportUuid, reporterId), modificationsUuidList)); case INSERT: - return ResponseEntity.ok().body(networkModificationService.insertCompositeModifications(targetGroupUuid, networkUuid, variantId, new ReportInfos(reportUuid, reporterId.toString()), modificationsUuidList)); + return ResponseEntity.ok().body(networkModificationService.insertCompositeModifications(targetGroupUuid, networkUuid, variantId, new ReportInfos(reportUuid, reporterId), modificationsUuidList)); case MOVE: UUID sourceGroupUuid = originGroupUuid == null ? targetGroupUuid : originGroupUuid; boolean canBuildNode = build; if (sourceGroupUuid.equals(targetGroupUuid)) { canBuildNode = false; } - return ResponseEntity.ok().body(networkModificationService.moveModifications(targetGroupUuid, sourceGroupUuid, beforeModificationUuid, networkUuid, variantId, new ReportInfos(reportUuid, reporterId.toString()), modificationsUuidList, canBuildNode)); + return ResponseEntity.ok().body(networkModificationService.moveModifications(targetGroupUuid, sourceGroupUuid, beforeModificationUuid, networkUuid, variantId, new ReportInfos(reportUuid, reporterId), modificationsUuidList, canBuildNode)); default: throw new NetworkModificationException(TYPE_MISMATCH); } @@ -134,7 +134,7 @@ public ResponseEntity> createNetworkModifica @Parameter(description = "Reporter ID") @RequestParam("reporterId") String reporterId, @RequestBody ModificationInfos modificationInfos) { modificationInfos.check(); - return ResponseEntity.ok().body(networkModificationService.createNetworkModification(networkUuid, variantId, groupUuid, new ReportInfos(reportUuid, reporterId), modificationInfos)); + return ResponseEntity.ok().body(networkModificationService.createNetworkModification(networkUuid, variantId, groupUuid, new ReportInfos(reportUuid, UUID.fromString(reporterId)), modificationInfos)); } @PutMapping(value = "/network-modifications/{uuid}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @@ -261,7 +261,7 @@ public ResponseEntity> duplicateModification @Parameter(description = "the reporter id", required = true) @RequestParam(value = "reporterId") UUID reporterId, @Parameter(description = "the variant id", required = true) @RequestParam(value = "variantId") String variantId, @Parameter(description = "origin group UUID, from where modifications are copied") @RequestParam(value = "duplicateFrom") UUID originGroupUuid) { - return ResponseEntity.ok().body(networkModificationService.duplicateModificationsInGroup(targetGroupUuid, networkUuid, variantId, new ReportInfos(reportUuid, reporterId.toString()), originGroupUuid)); + return ResponseEntity.ok().body(networkModificationService.duplicateModificationsInGroup(targetGroupUuid, networkUuid, variantId, new ReportInfos(reportUuid, reporterId), originGroupUuid)); } @DeleteMapping(value = "/groups/{groupUuid}/stashed-modifications") @@ -288,6 +288,6 @@ public ResponseEntity> applyModifications(@P @Parameter(description = "the report uuid") @RequestParam(value = "reportUuid", required = false) UUID reportUuid, @Parameter(description = "the reporter id") @RequestParam(value = "reporterId", required = false) String reporterId, @RequestBody List modificationsUuidList) { - return ResponseEntity.ok().body(networkModificationService.applyModificationsFromUuids(networkUuid, variantId, new ReportInfos(reportUuid, reporterId), modificationsUuidList)); + return ResponseEntity.ok().body(networkModificationService.applyModificationsFromUuids(networkUuid, variantId, new ReportInfos(reportUuid, UUID.fromString(reporterId)), modificationsUuidList)); } } diff --git a/src/main/java/org/gridsuite/modification/server/dto/BuildInfos.java b/src/main/java/org/gridsuite/modification/server/dto/BuildInfos.java index 285b3ec6c..ba8167728 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/BuildInfos.java +++ b/src/main/java/org/gridsuite/modification/server/dto/BuildInfos.java @@ -31,11 +31,9 @@ public class BuildInfos { private String destinationVariantId; - private UUID reportUuid; - private List modificationGroupUuids = new ArrayList<>(); - private List reporterIds = new ArrayList<>(); + private List reportsInfos = new ArrayList<>(); private Set modificationsToExclude = new HashSet<>(); diff --git a/src/main/java/org/gridsuite/modification/server/dto/ReportInfos.java b/src/main/java/org/gridsuite/modification/server/dto/ReportInfos.java index 07ff800ed..4cb14ecbf 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/ReportInfos.java +++ b/src/main/java/org/gridsuite/modification/server/dto/ReportInfos.java @@ -21,5 +21,5 @@ public class ReportInfos { private UUID reportUuid; - private String reporterId; + private UUID nodeUuid; } diff --git a/src/main/java/org/gridsuite/modification/server/modifications/NetworkModificationApplicator.java b/src/main/java/org/gridsuite/modification/server/modifications/NetworkModificationApplicator.java index b5c04dbfe..9ebdcb33d 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/NetworkModificationApplicator.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/NetworkModificationApplicator.java @@ -49,8 +49,6 @@ public class NetworkModificationApplicator { private static final Logger LOGGER = LoggerFactory.getLogger(NetworkModificationApplicator.class); - public static final String NETWORK_MODIFICATION_TYPE_REPORT = "NetworkModification"; - private final NetworkStoreService networkStoreService; private final EquipmentInfosService equipmentInfosService; @@ -126,7 +124,7 @@ private NetworkModificationResult processApplication(List mod * Note : it is possible that the rabbitmq consumer threads here will be blocked by modifications applied directly in the other applyModifications method * and no more builds can go through. If this causes problems we should put them in separate rabbitmq queues. */ - public NetworkModificationResult applyModifications(List>> modificationInfosGroups, NetworkInfos networkInfos, UUID reportUuid) { + public NetworkModificationResult applyModifications(List>> modificationInfosGroups, NetworkInfos networkInfos) { PreloadingStrategy preloadingStrategy = modificationInfosGroups.stream() .map(Pair::getRight) .flatMap(List::stream) @@ -135,19 +133,19 @@ public NetworkModificationResult applyModifications(List future = CompletableFuture.supplyAsync(() -> processApplication(modificationInfosGroups, networkInfos, reportUuid), applicationExecutor); + CompletableFuture future = CompletableFuture.supplyAsync(() -> processApplication(modificationInfosGroups, networkInfos), applicationExecutor); return future.join(); } else { - return processApplication(modificationInfosGroups, networkInfos, reportUuid); + return processApplication(modificationInfosGroups, networkInfos); } } // used for building a variant - private NetworkModificationResult processApplication(List>> modificationInfosGroups, NetworkInfos networkInfos, UUID reportUuid) { + private NetworkModificationResult processApplication(List>> modificationInfosGroups, NetworkInfos networkInfos) { NetworkStoreListener listener = NetworkStoreListener.create(networkInfos.getNetwork(), networkInfos.getNetworkUuuid(), networkStoreService, equipmentInfosService, collectionThreshold); List groupsApplicationStatuses = modificationInfosGroups.stream() - .map(g -> apply(g.getRight(), listener.getNetwork(), new ReportInfos(reportUuid, g.getLeft()))) + .map(g -> apply(g.getRight(), listener.getNetwork(), g.getLeft())) .toList(); List networkImpacts = listener.flushNetworkModifications(); return NetworkModificationResult.builder() @@ -159,9 +157,9 @@ private NetworkModificationResult processApplication(List modificationInfosList, Network network, ReportInfos reportInfos) { ReportNode reportNode; - if (reportInfos.getReporterId() != null) { - String rootReporterId = reportInfos.getReporterId() + "@" + NETWORK_MODIFICATION_TYPE_REPORT; - reportNode = ReportNode.newRootReportNode().withMessageTemplate(rootReporterId, rootReporterId).build(); + if (reportInfos.getNodeUuid() != null) { + UUID nodeUuid = reportInfos.getNodeUuid(); + reportNode = ReportNode.newRootReportNode().withMessageTemplate(nodeUuid.toString(), nodeUuid.toString()).build(); } else { reportNode = ReportNode.NO_OP; } diff --git a/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java b/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java index b4d59cf76..b3d21d658 100644 --- a/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java @@ -166,9 +166,9 @@ public Network cloneNetworkVariant(UUID networkUuid, @Transactional(readOnly = true) public NetworkModificationResult buildVariant(@NonNull UUID networkUuid, @NonNull BuildInfos buildInfos) { // Apply all modifications belonging to the modification groups uuids in buildInfos - List>> modificationInfos = new ArrayList<>(); + List>> modificationInfos = new ArrayList<>(); - Streams.forEachPair(buildInfos.getModificationGroupUuids().stream(), buildInfos.getReporterIds().stream(), + Streams.forEachPair(buildInfos.getModificationGroupUuids().stream(), buildInfos.getReportsInfos().stream(), (groupUuid, reporterId) -> { List modificationsByGroup = List.of(); try { @@ -199,7 +199,7 @@ public NetworkModificationResult buildVariant(@NonNull UUID networkUuid, @NonNul Network network = cloneNetworkVariant(networkUuid, buildInfos.getOriginVariantId(), buildInfos.getDestinationVariantId(), preloadingStrategy); NetworkInfos networkInfos = new NetworkInfos(network, networkUuid, true); - return modificationApplicator.applyModifications(modificationInfos, networkInfos, buildInfos.getReportUuid()); + return modificationApplicator.applyModifications(modificationInfos, networkInfos); } public void buildVariantRequest(UUID networkUuid, BuildInfos buildInfos, String receiver) { diff --git a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java index 9cef9cf90..a562f4623 100644 --- a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java +++ b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java @@ -1637,7 +1637,7 @@ public void testApplyModificationsFromUuids() throws Exception { // apply the modification on the network mvcResult = mockMvc.perform( put("/v1/networks/" + TEST_NETWORK_ID + "/apply" - + "?variantId=" + NetworkCreation.VARIANT_ID) + + "?variantId=" + NetworkCreation.VARIANT_ID + "&reporterId=" + UUID.randomUUID().toString()) .content(objectWriter.writeValueAsString(modificationUuidList)) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()).andReturn(); diff --git a/src/test/java/org/gridsuite/modification/server/VoltageInitReportTest.java b/src/test/java/org/gridsuite/modification/server/VoltageInitReportTest.java index 497efc1ca..f123c3331 100644 --- a/src/test/java/org/gridsuite/modification/server/VoltageInitReportTest.java +++ b/src/test/java/org/gridsuite/modification/server/VoltageInitReportTest.java @@ -79,7 +79,7 @@ void testVoltageInitDuplicationLogs(final ApplicationStatus resultStatus, final assertThat(networkModificationApplicator.applyModifications( List.of(modificationInfos), new NetworkInfos(network, networkUuuid, true), - new ReportInfos(reportUuid, "99999999-9999-9999-9999-999999999999"))) + new ReportInfos(reportUuid, UUID.fromString("99999999-9999-9999-9999-999999999999")))) .as("network modifications results") .isNotNull() .extracting(NetworkModificationResult::getApplicationStatus) diff --git a/src/test/java/org/gridsuite/modification/server/modifications/CompositeModificationsTest.java b/src/test/java/org/gridsuite/modification/server/modifications/CompositeModificationsTest.java index b0dbef66f..d58b68582 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/CompositeModificationsTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/CompositeModificationsTest.java @@ -48,14 +48,15 @@ public class CompositeModificationsTest extends AbstractNetworkModificationTest @Before public void specificSetUp() { // Currently we never apply composite modifications (apply mocked) - NetworkModificationResult networkModificationResultMock = - NetworkModificationResult.builder() - .applicationStatus(NetworkModificationResult.ApplicationStatus.ALL_OK) - .lastGroupApplicationStatus(NetworkModificationResult.ApplicationStatus.ALL_OK) - .networkImpacts(List.of()) - .build(); - when(networkModificationApplicator.applyModifications(any(), any(), any(ReportInfos.class))).then((Answer) invocation -> networkModificationResultMock); - when(networkModificationApplicator.applyModifications(any(), any(), any(UUID.class))).then((Answer) invocation -> networkModificationResultMock); + NetworkModificationResult networkModificationResultMock = NetworkModificationResult.builder() + .applicationStatus(NetworkModificationResult.ApplicationStatus.ALL_OK) + .lastGroupApplicationStatus(NetworkModificationResult.ApplicationStatus.ALL_OK) + .networkImpacts(List.of()) + .build(); + when(networkModificationApplicator.applyModifications(any(), any(), any(ReportInfos.class))) + .then((Answer) invocation -> networkModificationResultMock); + when(networkModificationApplicator.applyModifications(any(), any(), any(ReportInfos.class))) + .then((Answer) invocation -> networkModificationResultMock); } @Override @@ -66,10 +67,10 @@ protected Network createNetwork(UUID networkUuid) { @Override protected ModificationInfos buildModification() { List modifications = List.of( - ModificationCreation.getCreationGenerator("v1", "idGenerator", "nameGenerator", "1B", "v2load", "LOAD", "v1"), + ModificationCreation.getCreationGenerator("v1", "idGenerator", "nameGenerator", "1B", "v2load", "LOAD", + "v1"), ModificationCreation.getCreationLoad("v1", "idLoad", "nameLoad", "1.1", LoadType.UNDEFINED), - ModificationCreation.getCreationBattery("v1", "idBattery", "nameBattry", "1.1") - ); + ModificationCreation.getCreationBattery("v1", "idBattery", "nameBattry", "1.1")); return CompositeModificationInfos.builder() .modifications(modifications) .stashed(false) @@ -107,7 +108,7 @@ public void testCheckSqlRequestsCount() throws Exception { SQLStatementCountValidator.reset(); mockMvc.perform(get("/v1/network-modifications/{uuid}", modificationUuid)).andExpectAll( - status().isOk(), content().contentType(MediaType.APPLICATION_JSON)) + status().isOk(), content().contentType(MediaType.APPLICATION_JSON)) .andReturn(); assertSelectCount(7); SQLStatementCountValidator.reset(); diff --git a/src/test/java/org/gridsuite/modification/server/service/BuildTest.java b/src/test/java/org/gridsuite/modification/server/service/BuildTest.java index a9e4cc460..a75f0a568 100644 --- a/src/test/java/org/gridsuite/modification/server/service/BuildTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/BuildTest.java @@ -66,7 +66,6 @@ import static com.powsybl.iidm.network.ReactiveLimitsKind.MIN_MAX; import static org.gridsuite.modification.server.Impacts.TestImpactUtils.*; -import static org.gridsuite.modification.server.modifications.NetworkModificationApplicator.NETWORK_MODIFICATION_TYPE_REPORT; import static org.gridsuite.modification.server.service.BuildWorkerService.CANCEL_MESSAGE; import static org.gridsuite.modification.server.service.BuildWorkerService.FAIL_MESSAGE; import static org.hamcrest.MatcherAssert.assertThat; @@ -97,11 +96,10 @@ public class BuildTest { private static final UUID TEST_NETWORK_STOP_BUILD_ID = UUID.fromString("11111111-7977-4592-ba19-88027e4254e4"); private static final UUID TEST_GROUP_ID = UUID.randomUUID(); private static final UUID TEST_GROUP_ID_2 = UUID.randomUUID(); - private static final UUID TEST_REPORT_ID = UUID.randomUUID(); private static final UUID TEST_ERROR_REPORT_ID = UUID.randomUUID(); - private static final String TEST_SUB_REPORTER_ID_1 = UUID.randomUUID().toString(); - private static final String TEST_SUB_REPORTER_ID_2 = UUID.randomUUID().toString(); + private static final UUID TEST_SUB_REPORTER_ID_1 = UUID.randomUUID(); + private static final UUID TEST_SUB_REPORTER_ID_2 = UUID.randomUUID(); private static final int TIMEOUT = 1000; @@ -281,9 +279,8 @@ public void runBuildForLineSplits() throws Exception { String uriString = "/v1/networks/{networkUuid}/build?receiver=me"; BuildInfos buildInfos = new BuildInfos(VariantManagerConstants.INITIAL_VARIANT_ID, NetworkCreation.VARIANT_ID, - TEST_REPORT_ID, List.of(TEST_GROUP_ID, TEST_GROUP_ID_2), - List.of(TEST_SUB_REPORTER_ID_1, TEST_SUB_REPORTER_ID_2), + List.of(new ReportInfos(UUID.randomUUID(), TEST_SUB_REPORTER_ID_1), new ReportInfos(UUID.randomUUID(), TEST_SUB_REPORTER_ID_2)), new HashSet<>()); mockMvc.perform(post(uriString, TEST_NETWORK_ID) .contentType(MediaType.APPLICATION_JSON) @@ -299,7 +296,6 @@ public void runBuildForLineSplits() throws Exception { BuildInfos newBuildInfos = new BuildInfos(NetworkCreation.VARIANT_ID, VARIANT_ID_2, - TEST_REPORT_ID, List.of(), List.of(), new HashSet<>()); @@ -325,12 +321,11 @@ public void runBuildWithEmptyGroupTest() throws Exception { Network network = NetworkCreation.create(TEST_NETWORK_ID, false); BuildInfos buildInfos = new BuildInfos(VariantManagerConstants.INITIAL_VARIANT_ID, NetworkCreation.VARIANT_ID, - TEST_REPORT_ID, List.of(TEST_GROUP_ID), - List.of(TEST_SUB_REPORTER_ID_1), + List.of(new ReportInfos(UUID.randomUUID(), TEST_SUB_REPORTER_ID_1)), new HashSet<>()); String expectedBody = mapper.writeValueAsString(ReportNode.newRootReportNode() - .withMessageTemplate(TEST_SUB_REPORTER_ID_1 + "@" + NETWORK_MODIFICATION_TYPE_REPORT, TEST_SUB_REPORTER_ID_1 + "@" + NETWORK_MODIFICATION_TYPE_REPORT) + .withMessageTemplate(TEST_SUB_REPORTER_ID_1.toString(), TEST_SUB_REPORTER_ID_1.toString()) .build()); // Group does not exist @@ -429,9 +424,8 @@ public void testIndexationAfterBuild() throws Exception { // Create build infos BuildInfos buildInfos = new BuildInfos(VariantManagerConstants.INITIAL_VARIANT_ID, NetworkCreation.VARIANT_ID, - TEST_REPORT_ID, List.of(TEST_GROUP_ID), - List.of(TEST_SUB_REPORTER_ID_1), + List.of(new ReportInfos(UUID.randomUUID(), TEST_SUB_REPORTER_ID_1)), new HashSet<>()); // Build variant @@ -709,9 +703,8 @@ public void runBuildTest() throws Exception { String uriString = "/v1/networks/{networkUuid}/build?receiver=me"; BuildInfos buildInfos = new BuildInfos(VariantManagerConstants.INITIAL_VARIANT_ID, NetworkCreation.VARIANT_ID, - TEST_REPORT_ID, List.of(TEST_GROUP_ID, TEST_GROUP_ID_2), - List.of(TEST_SUB_REPORTER_ID_1, TEST_SUB_REPORTER_ID_2), + List.of(new ReportInfos(UUID.randomUUID(), TEST_SUB_REPORTER_ID_1), new ReportInfos(UUID.randomUUID(), TEST_SUB_REPORTER_ID_2)), new HashSet<>()); String buildInfosJson = objectWriter.writeValueAsString(buildInfos); mockMvc.perform(post(uriString, TEST_NETWORK_ID).contentType(MediaType.APPLICATION_JSON).content(buildInfosJson)) @@ -809,7 +802,6 @@ public void runBuildTest() throws Exception { // to check BuildInfos newBuildInfos = new BuildInfos(NetworkCreation.VARIANT_ID, VARIANT_ID_2, - TEST_REPORT_ID, Collections.emptyList(), Collections.emptyList(), new HashSet<>()); @@ -926,9 +918,8 @@ public void runBuildWithStashedModificationsTest() throws Exception { BuildInfos buildInfos = new BuildInfos(VariantManagerConstants.INITIAL_VARIANT_ID, NetworkCreation.VARIANT_ID, - TEST_REPORT_ID, List.of(TEST_GROUP_ID), - List.of(TEST_SUB_REPORTER_ID_1), + List.of(new ReportInfos(UUID.randomUUID(), TEST_SUB_REPORTER_ID_1)), new HashSet<>()); networkModificationService.buildVariant(TEST_NETWORK_ID, buildInfos); @@ -953,9 +944,8 @@ public void stopBuildTest() throws Exception { // Because TestChannelBinder implementation is synchronous the build is made in a different thread BuildInfos buildInfos = new BuildInfos(VariantManagerConstants.INITIAL_VARIANT_ID, NetworkCreation.VARIANT_ID, - TEST_REPORT_ID, List.of(TEST_GROUP_ID), - List.of(TEST_SUB_REPORTER_ID_1), + List.of(new ReportInfos(UUID.randomUUID(), TEST_SUB_REPORTER_ID_1)), Set.of()); String buildInfosJson = mapper.writeValueAsString(buildInfos); CompletableFuture.runAsync(() -> { @@ -993,9 +983,8 @@ public void runBuildWithReportErrorTest() throws Exception { String uriString = "/v1/networks/{networkUuid}/build?receiver=me"; BuildInfos buildInfos = new BuildInfos(VariantManagerConstants.INITIAL_VARIANT_ID, NetworkCreation.VARIANT_ID, - TEST_ERROR_REPORT_ID, List.of(TEST_GROUP_ID), - List.of(TEST_SUB_REPORTER_ID_1), + List.of(new ReportInfos(TEST_ERROR_REPORT_ID, TEST_SUB_REPORTER_ID_1)), Set.of()); mockMvc.perform(post(uriString, TEST_NETWORK_ID) .contentType(MediaType.APPLICATION_JSON) @@ -1019,7 +1008,7 @@ public void testApplyModificationWithErrors() { LoadCreationInfos loadCreationInfos = LoadCreationInfos.builder().voltageLevelId("unknownVoltageLevelId").equipmentId("loadId").build(); UUID groupUuid = UUID.randomUUID(); UUID reportUuid = UUID.randomUUID(); - String reporterId = UUID.randomUUID().toString(); + UUID reporterId = UUID.randomUUID(); String variantId = network.getVariantManager().getWorkingVariantId(); // Building mode : No error send with exception @@ -1045,15 +1034,15 @@ public void testLastGroupModificationStatus() { Network network = NetworkCreation.create(TEST_NETWORK_ID, true); LoadCreationInfos loadCreationInfos = LoadCreationInfos.builder().voltageLevelId("unknownVoltageLevelId").equipmentId("loadId").build(); UUID reportUuid = UUID.randomUUID(); - String reporterId = UUID.randomUUID().toString(); - String reporterId2 = UUID.randomUUID().toString(); + UUID nodeUuid1 = UUID.randomUUID(); + UUID nodeUuid2 = UUID.randomUUID(); - List>> modificationInfosGroups = new ArrayList<>(); - modificationInfosGroups.add(Pair.of(reporterId, List.of(loadCreationInfos))); - modificationInfosGroups.add(Pair.of(reporterId2, List.of())); + List>> modificationInfosGroups = new ArrayList<>(); + modificationInfosGroups.add(Pair.of(new ReportInfos(reportUuid, nodeUuid1), List.of(loadCreationInfos))); + modificationInfosGroups.add(Pair.of(new ReportInfos(UUID.randomUUID(), nodeUuid2), List.of())); //Global application status should be in error and last application status should be OK - NetworkModificationResult networkModificationResult = networkModificationApplicator.applyModifications(modificationInfosGroups, new NetworkInfos(network, TEST_NETWORK_ID, true), reportUuid); + NetworkModificationResult networkModificationResult = networkModificationApplicator.applyModifications(modificationInfosGroups, new NetworkInfos(network, TEST_NETWORK_ID, true)); assertNotNull(networkModificationResult); testEmptyImpactsWithErrorsLastOK(networkModificationResult); assertTrue(TestUtils.getRequestsDone(2, server).stream().anyMatch(r -> r.matches(String.format("/v1/reports/%s", reportUuid)))); diff --git a/src/test/resources/reports_voltage_init_modification_ok.json b/src/test/resources/reports_voltage_init_modification_ok.json index 7a83e9905..86e3b5e99 100644 --- a/src/test/resources/reports_voltage_init_modification_ok.json +++ b/src/test/resources/reports_voltage_init_modification_ok.json @@ -4,7 +4,7 @@ "default": { "2WindingsTransformerModification": "2 windings transformer with id=${id} modified :", "2WindingsTransformersModifications": "2 windings transformers", - "99999999-9999-9999-9999-999999999999@NetworkModification": "99999999-9999-9999-9999-999999999999@NetworkModification", + "99999999-9999-9999-9999-999999999999": "99999999-9999-9999-9999-999999999999", "GeneratorsModifications": "Generators", "ShuntCompensatorsModifications": "Shunt compensators", "StaticVarCompensatorsModifications": "Static var compensators", @@ -24,7 +24,7 @@ } }, "reportRoot": { - "messageKey": "99999999-9999-9999-9999-999999999999@NetworkModification", + "messageKey": "99999999-9999-9999-9999-999999999999", "children": [ { "messageKey": "VOLTAGE_INIT_MODIFICATION", diff --git a/src/test/resources/reports_voltage_init_modification_warnings.json b/src/test/resources/reports_voltage_init_modification_warnings.json index c13ab1fed..141b9f2d0 100644 --- a/src/test/resources/reports_voltage_init_modification_warnings.json +++ b/src/test/resources/reports_voltage_init_modification_warnings.json @@ -6,7 +6,7 @@ "2WindingsTransformersModifications": "2 windings transformers", "3WindingsTransformerNotFound": "3 windings transformer with id=${id} not found", "3WindingsTransformersModifications": "3 windings transformers", - "99999999-9999-9999-9999-999999999999@NetworkModification": "99999999-9999-9999-9999-999999999999@NetworkModification", + "99999999-9999-9999-9999-999999999999": "99999999-9999-9999-9999-999999999999", "GeneratorsModifications": "Generators", "ShuntCompensatorsModifications": "Shunt compensators", "StaticVarCompensatorsModifications": "Static var compensators", @@ -21,7 +21,7 @@ } }, "reportRoot": { - "messageKey": "99999999-9999-9999-9999-999999999999@NetworkModification", + "messageKey": "99999999-9999-9999-9999-999999999999", "children": [ { "messageKey": "VOLTAGE_INIT_MODIFICATION", From 049ebae8de1f30887d4d1361bc636c35c336e464 Mon Sep 17 00:00:00 2001 From: Ghazoua Rehili Date: Thu, 3 Oct 2024 09:36:32 +0200 Subject: [PATCH 4/6] handle connectablePosition extension in modification network (#539) Signed-off-by: REHILI Ghazwa --- .../modifications/ModificationUtils.java | 160 ++++++++++++------ .../modifications/LineModificationTest.java | 22 +++ .../server/utils/NetworkCreation.java | 2 +- .../server/utils/NetworkUtil.java | 20 ++- 4 files changed, 152 insertions(+), 52 deletions(-) diff --git a/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java b/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java index c2b94e850..b68ecc296 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java @@ -609,7 +609,7 @@ public ReportNode modifyInjectionConnectivityAttributes(ConnectablePosition c if (isVoltageOrBusbarIdMissing(modificationInfos.getVoltageLevelId(), modificationInfos.getBusOrBusbarSectionId(), modificationInfos.getEquipmentId(), reports)) { return reports.get(0); } - processConnectivityPosition(connectablePosition, connectablePositionAdder, modificationInfos, reports, false); + processConnectivityPosition(connectablePosition, connectablePositionAdder, modificationInfos, injection.getNetwork(), reports, false); modifyConnection(modificationInfos.getTerminalConnected(), injection, injection.getTerminal(), reports); return reportModifications(connectivityReports, reports, "ConnectivityModified", CONNECTIVITY); @@ -626,7 +626,7 @@ public ReportNode modifyBranchConnectivityAttributes(ConnectablePosition conn return reports.get(0); } - processConnectivityPosition(connectablePosition, connectablePositionAdder, modificationInfos, reports, true); + processConnectivityPosition(connectablePosition, connectablePositionAdder, modificationInfos, branch.getNetwork(), reports, true); modifyConnection(modificationInfos.getTerminal1Connected(), branch, branch.getTerminal1(), reports); modifyConnection(modificationInfos.getTerminal2Connected(), branch, branch.getTerminal2(), reports); @@ -648,53 +648,54 @@ private boolean isVoltageOrBusbarIdMissing(AttributeModification voltage private void processConnectivityPosition(ConnectablePosition connectablePosition, ConnectablePositionAdder connectablePositionAdder, - Object modificationInfos, + BasicEquipmentModificationInfos modificationInfos, + Network network, List reports, boolean isBranch) { if (connectablePosition != null) { modifyExistingConnectivityPosition(connectablePosition, modificationInfos, reports, isBranch); } else { - createNewConnectivityPosition(connectablePositionAdder, modificationInfos, reports, isBranch); + createNewConnectivityPosition(connectablePositionAdder, modificationInfos, network, reports, isBranch); } } private void modifyExistingConnectivityPosition(ConnectablePosition connectablePosition, - Object modificationInfos, + BasicEquipmentModificationInfos modificationInfos, List reports, boolean isBranch) { if (isBranch) { - modifyFeeder(connectablePosition.getFeeder1(), modificationInfos, reports, 1); - modifyFeeder(connectablePosition.getFeeder2(), modificationInfos, reports, 2); + modifyConnectablePosition(connectablePosition.getFeeder1(), modificationInfos, reports, 1); + modifyConnectablePosition(connectablePosition.getFeeder2(), modificationInfos, reports, 2); } else { - modifyFeeder(connectablePosition.getFeeder(), modificationInfos, reports, 0); + modifyConnectablePosition(connectablePosition.getFeeder(), modificationInfos, reports, 0); } } private void createNewConnectivityPosition(ConnectablePositionAdder adder, - Object modificationInfos, + BasicEquipmentModificationInfos modificationInfos, + Network network, List reports, boolean isBranch) { if (isBranch) { - ConnectablePositionAdder.FeederAdder feeder1 = adder.newFeeder1(); - ConnectablePositionAdder.FeederAdder feeder2 = adder.newFeeder2(); - modifyFeederAdder(feeder1, modificationInfos, reports, 1); - modifyFeederAdder(feeder2, modificationInfos, reports, 2); + ConnectablePositionAdder.FeederAdder feederAdder1 = adder.newFeeder1(); + ConnectablePositionAdder.FeederAdder feederAdder2 = adder.newFeeder2(); + addConnectablePosition(adder, feederAdder1, modificationInfos, network, reports, 1); + addConnectablePosition(adder, feederAdder2, modificationInfos, network, reports, 2); } else { - ConnectablePositionAdder.FeederAdder feeder = adder.newFeeder(); - modifyFeederAdder(feeder, modificationInfos, reports, 0); + ConnectablePositionAdder.FeederAdder feederAdder = adder.newFeeder(); + addConnectablePosition(adder, feederAdder, modificationInfos, network, reports, 0); } - adder.add(); } - private void modifyFeeder(ConnectablePosition.Feeder feeder, - Object modificationInfos, - List reports, - int feederNumber) { + private void modifyConnectablePosition(ConnectablePosition.Feeder feeder, + BasicEquipmentModificationInfos modificationInfos, + List reports, + int feederNumber) { applyModifications(feeder, modificationInfos, reports, feederNumber); } private void applyModifications(ConnectablePosition.Feeder feeder, - Object modificationInfos, + BasicEquipmentModificationInfos modificationInfos, List reports, int feederNumber) { ReportNode connectionNameReport = applyElementaryModificationsAndReturnReport(feeder::setName, @@ -720,37 +721,68 @@ private void applyModifications(ConnectablePosition.Feeder feeder, } } - private void modifyFeederAdder(ConnectablePositionAdder.FeederAdder feeder, - Object modificationInfos, - List reports, - int feederNumber) { - ReportNode connectionNameReport = applyElementaryModificationsAndReturnReport(feeder::withName, - () -> null, - getConnectionName(modificationInfos, feederNumber), - getConnectionNameField(feederNumber)); - if (connectionNameReport != null) { - reports.add(connectionNameReport); - } - ReportNode connectionDirectionReport = applyElementaryModificationsAndReturnReport(feeder::withDirection, - () -> null, - getConnectionDirection(modificationInfos, feederNumber), - getConnectionDirectionField(feederNumber)); - if (connectionDirectionReport != null) { - reports.add(connectionDirectionReport); - } - ReportNode connectionPositionReport = applyElementaryModificationsAndReturnReport(feeder::withOrder, - () -> null, - getConnectionPosition(modificationInfos, feederNumber), - getConnectionPositionField(feederNumber)); - if (connectionPositionReport != null) { - reports.add(connectionPositionReport); - } + private void addConnectablePosition(ConnectablePositionAdder adder, + ConnectablePositionAdder.FeederAdder feeder, + BasicEquipmentModificationInfos modificationInfos, + Network network, + List reports, + int feederNumber) { + AttributeModification connectionName = getConnectionName(modificationInfos, feederNumber); + AttributeModification connectionDirection = getConnectionDirection(modificationInfos, feederNumber); + AttributeModification connectionPosition = getConnectionPosition(modificationInfos, feederNumber); + AttributeModification equipmentId = getEquipmentId(modificationInfos); + AttributeModification voltageLevelId = getVoltageLevelId(modificationInfos, feederNumber); + AttributeModification busOrBusbarSectionId = getBusOrBusbarSectionId(modificationInfos, feederNumber); + int position = getPosition(connectionPosition, busOrBusbarSectionId, network, voltageLevelId); + + ReportNode connectionNameReport = applyConnectablePositionAttribute( + feeder::withName, connectionName, equipmentId, reports, + getConnectionNameField(feederNumber), connectionDirection, connectionPosition + ); + + ReportNode connectionDirectionReport = applyConnectablePositionAttribute( + feeder::withDirection, connectionDirection, + new AttributeModification<>(ConnectablePosition.Direction.UNDEFINED, OperationType.SET), + reports, getConnectionDirectionField(feederNumber), + connectionName, connectionPosition + ); + + ReportNode connectionPositionReport = applyConnectablePositionAttribute( + feeder::withOrder, connectionPosition, + new AttributeModification<>(position, OperationType.SET), + reports, getConnectionPositionField(feederNumber), + connectionName, connectionDirection + ); + if (connectionNameReport != null || connectionDirectionReport != null || connectionPositionReport != null) { feeder.add(); + adder.add(); } } - private T getConnectionDetail(Object modificationInfos, int feederNumber, + private ReportNode applyConnectablePositionAttribute(Consumer setter, + AttributeModification newValue, + AttributeModification defaultValue, + List reports, + String fieldName, + AttributeModification... dependentAttributes) { + + AttributeModification finalModification = (newValue == null && isAnyAttributesNonNull(dependentAttributes)) + ? defaultValue + : newValue; + + ReportNode report = applyElementaryModificationsAndReturnReport(setter, () -> null, finalModification, fieldName); + if (report != null) { + reports.add(report); + } + return report; + } + + private boolean isAnyAttributesNonNull(AttributeModification... attributes) { + return Arrays.stream(attributes).anyMatch(Objects::nonNull); + } + + private T getConnectionDetail(BasicEquipmentModificationInfos modificationInfos, int feederNumber, Function branchFunc1, Function branchFunc2, Function injectionFunc) { @@ -771,7 +803,23 @@ private String getConnectionFieldName(int feederNumber, String baseFieldName) { }; } - private AttributeModification getConnectionName(Object modificationInfos, int feederNumber) { + private AttributeModification getVoltageLevelId(BasicEquipmentModificationInfos modificationInfos, int feederNumber) { + return getConnectionDetail(modificationInfos, feederNumber, + BranchModificationInfos::getVoltageLevelId1, BranchModificationInfos::getVoltageLevelId2, + InjectionModificationInfos::getVoltageLevelId); + } + + private AttributeModification getBusOrBusbarSectionId(BasicEquipmentModificationInfos modificationInfos, int feederNumber) { + return getConnectionDetail(modificationInfos, feederNumber, + BranchModificationInfos::getBusOrBusbarSectionId1, BranchModificationInfos::getBusOrBusbarSectionId2, + InjectionModificationInfos::getBusOrBusbarSectionId); + } + + private AttributeModification getEquipmentId(BasicEquipmentModificationInfos modificationInfos) { + return AttributeModification.toAttributeModification(modificationInfos.getEquipmentId(), OperationType.SET); + } + + private AttributeModification getConnectionName(BasicEquipmentModificationInfos modificationInfos, int feederNumber) { return getConnectionDetail(modificationInfos, feederNumber, BranchModificationInfos::getConnectionName1, BranchModificationInfos::getConnectionName2, InjectionModificationInfos::getConnectionName); @@ -789,18 +837,30 @@ private String getConnectionPositionField(int feederNumber) { return getConnectionFieldName(feederNumber, CONNECTION_POSITION_FIELD_NAME); } - private AttributeModification getConnectionDirection(Object modificationInfos, int feederNumber) { + private AttributeModification getConnectionDirection(BasicEquipmentModificationInfos modificationInfos, int feederNumber) { return getConnectionDetail(modificationInfos, feederNumber, BranchModificationInfos::getConnectionDirection1, BranchModificationInfos::getConnectionDirection2, InjectionModificationInfos::getConnectionDirection); } - private AttributeModification getConnectionPosition(Object modificationInfos, int feederNumber) { + private AttributeModification getConnectionPosition(BasicEquipmentModificationInfos modificationInfos, int feederNumber) { return getConnectionDetail(modificationInfos, feederNumber, BranchModificationInfos::getConnectionPosition1, BranchModificationInfos::getConnectionPosition2, InjectionModificationInfos::getConnectionPosition); } + private int getPosition(AttributeModification connectionPosition, + AttributeModification busOrBusbarSectionId, + Network network, + AttributeModification voltageLevelId) { + return getPosition( + connectionPosition == null ? null : connectionPosition.getValue(), + busOrBusbarSectionId == null ? null : busOrBusbarSectionId.getValue(), + network, + getVoltageLevel(network, voltageLevelId == null ? null : voltageLevelId.getValue()) + ); + } + private void modifyConnection(AttributeModification terminalConnected, Identifiable equipment, Terminal terminal, List reports) { if (terminalConnected == null || equipment == null) { return; diff --git a/src/test/java/org/gridsuite/modification/server/modifications/LineModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/LineModificationTest.java index 69af786b8..109581464 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/LineModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/LineModificationTest.java @@ -423,4 +423,26 @@ private void changeLineConnectionState(Line existingEquipment, boolean expectedS assertThat(existingEquipment.getTerminal1().isConnected()).isEqualTo(expectedState); assertThat(existingEquipment.getTerminal2().isConnected()).isEqualTo(expectedState); } + + @Test + public void changeLineConnectablePosition() throws Exception { + LineModificationInfos lineModificationInfos = LineModificationInfos.builder() + .stashed(false) + .equipmentId("line3") + .equipmentName(new AttributeModification<>("LineModified", OperationType.SET)) + .voltageLevelId1(new AttributeModification<>("v1", OperationType.SET)) + .voltageLevelId2(new AttributeModification<>("v3", OperationType.SET)) + .busOrBusbarSectionId1(new AttributeModification<>("1B", OperationType.SET)) + .busOrBusbarSectionId2(new AttributeModification<>("2B", OperationType.SET)) + .connectionPosition1(new AttributeModification<>(1, OperationType.SET)) + .connectionPosition2(new AttributeModification<>(1, OperationType.SET)) + .build(); + String modificationInfosJson = mapper.writeValueAsString(lineModificationInfos); + mockMvc.perform(post(getNetworkModificationUri()).content(modificationInfosJson).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + LineModificationInfos createdModification = (LineModificationInfos) modificationRepository.getModifications(getGroupId(), false, true).get(0); + assertEquals(1, createdModification.getConnectionPosition1().getValue()); + assertEquals(1, createdModification.getConnectionPosition2().getValue()); + + } } diff --git a/src/test/java/org/gridsuite/modification/server/utils/NetworkCreation.java b/src/test/java/org/gridsuite/modification/server/utils/NetworkCreation.java index a5c228386..9c90abbb3 100644 --- a/src/test/java/org/gridsuite/modification/server/utils/NetworkCreation.java +++ b/src/test/java/org/gridsuite/modification/server/utils/NetworkCreation.java @@ -288,7 +288,7 @@ public static Network create(UUID uuid, boolean createHvdcLine, NetworkFactory n createSwitch(v3, "v3dl2", "v3dl2", SwitchKind.DISCONNECTOR, true, false, false, 0, 30); createSwitch(v3, "v3bl2", "v3bl2", SwitchKind.BREAKER, true, false, false, 30, 31); - createLine(network, "line3", "line3", "v1", "v3", 10, 12, 12.0, 7.0, 5.5, 7.5, 6.5, 8.5, "cn1line3", 3, ConnectablePosition.Direction.TOP, "cn2line3", 3, ConnectablePosition.Direction.TOP); + createLineWithoutConnectivity(network, "line3", "line3", "v1", "v3", 10, 12, 12.0, 7.0, 5.5, 7.5, 6.5, 8.5); createSwitch(v1, "v1dl3", "v1dl3", SwitchKind.DISCONNECTOR, true, false, false, 0, 9); createSwitch(v1, "v1bl3", "v1bl3", SwitchKind.BREAKER, true, false, true, 9, 10); createSwitch(v3, "v3dl3", "v3dl3", SwitchKind.DISCONNECTOR, true, false, false, 0, 11); diff --git a/src/test/java/org/gridsuite/modification/server/utils/NetworkUtil.java b/src/test/java/org/gridsuite/modification/server/utils/NetworkUtil.java index 9507ab3f5..bd038d7b7 100644 --- a/src/test/java/org/gridsuite/modification/server/utils/NetworkUtil.java +++ b/src/test/java/org/gridsuite/modification/server/utils/NetworkUtil.java @@ -106,6 +106,24 @@ public static void createLine(Network network, String id, String name, String vo .add(); } + public static void createLineWithoutConnectivity(Network network, String id, String name, String voltageLevel1, String voltageLevel2, int node1, int node2, + double r, double x, double g1, double g2, double b1, double b2) { + network.newLine() + .setId(id) + .setName(name) + .setR(r) + .setX(x) + .setG1(g1) + .setG2(g2) + .setB1(b1) + .setB2(b2) + .setVoltageLevel1(voltageLevel1) + .setVoltageLevel2(voltageLevel2) + .setNode1(node1) + .setNode2(node2) + .add(); + } + @SuppressWarnings("SameParameterValue") public static void createLoad(VoltageLevel vl, String id, String name, int node, double p0, double q0, String feederName, int feederOrder, ConnectablePosition.Direction direction) { @@ -160,7 +178,7 @@ public static void createGenerator(VoltageLevel vl, String id, int node, double } public static void createGeneratorOnBus(VoltageLevel vl, String id, String busId, double targetP, double targetQ) { - var g = vl.newGenerator() + vl.newGenerator() .setId(id) .setName(id) .setTargetP(targetP) From 6ab069a12902b040c38cfa856d6457d3a68389ab Mon Sep 17 00:00:00 2001 From: FranckLecuyer <47824306+FranckLecuyer@users.noreply.github.com> Date: Thu, 3 Oct 2024 13:54:44 +0200 Subject: [PATCH 5/6] Fix npe when reporterId is null (#540) Signed-off-by: Franck LECUYER --- .../server/NetworkModificationController.java | 2 +- .../server/ModificationControllerTest.java | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java index ac91b8ab0..b8e6bddce 100644 --- a/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java +++ b/src/main/java/org/gridsuite/modification/server/NetworkModificationController.java @@ -288,6 +288,6 @@ public ResponseEntity> applyModifications(@P @Parameter(description = "the report uuid") @RequestParam(value = "reportUuid", required = false) UUID reportUuid, @Parameter(description = "the reporter id") @RequestParam(value = "reporterId", required = false) String reporterId, @RequestBody List modificationsUuidList) { - return ResponseEntity.ok().body(networkModificationService.applyModificationsFromUuids(networkUuid, variantId, new ReportInfos(reportUuid, UUID.fromString(reporterId)), modificationsUuidList)); + return ResponseEntity.ok().body(networkModificationService.applyModificationsFromUuids(networkUuid, variantId, new ReportInfos(reportUuid, reporterId != null ? UUID.fromString(reporterId) : null), modificationsUuidList)); } } diff --git a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java index a562f4623..ee2c5bafa 100644 --- a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java +++ b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java @@ -1634,10 +1634,10 @@ public void testApplyModificationsFromUuids() throws Exception { assertNotNull(sw); assertFalse(sw.isOpen()); // switch is closed - // apply the modification on the network + // apply the modification on the network with a reporterId mvcResult = mockMvc.perform( put("/v1/networks/" + TEST_NETWORK_ID + "/apply" - + "?variantId=" + NetworkCreation.VARIANT_ID + "&reporterId=" + UUID.randomUUID().toString()) + + "?variantId=" + NetworkCreation.VARIANT_ID + "&reporterId=" + UUID.randomUUID()) .content(objectWriter.writeValueAsString(modificationUuidList)) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()).andReturn(); @@ -1651,5 +1651,14 @@ public void testApplyModificationsFromUuids() throws Exception { assertEquals(modificationUuidList, newModificationUuidList); assertTrue(sw.isOpen()); // switch is opened + + // apply the modification on the network without reporterId + mvcResult = mockMvc.perform( + put("/v1/networks/" + TEST_NETWORK_ID + "/apply" + + "?variantId=" + NetworkCreation.VARIANT_ID) + .content(objectWriter.writeValueAsString(modificationUuidList)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + assertApplicationStatusOK(mvcResult); } } From ffd24f760cedf6ab336cdd1257076137a374f3f4 Mon Sep 17 00:00:00 2001 From: Thang PHAM <117309322+thangqp@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:19:54 +0200 Subject: [PATCH 6/6] Modification by filter (without formula data migration) (#526) Signed-off-by: Thang PHAM byfilter}/formula/FormulaInfos.java | 21 +- .../dto/{ => byfilter}/formula/Operator.java | 2 +- .../formula/ReferenceFieldOrValue.java | 50 ++ .../dto/formula/ReferenceFieldOrValue.java | 68 --- .../equipmentfield/GeneratorField.java | 109 ---- .../byfilter/AbstractAssignmentEntity.java | 39 ++ .../ByFormulaModificationEntity.java | 10 +- .../ModificationByAssignmentEntity.java | 83 +++ .../byfilter/assignment/AssignmentEntity.java | 79 +++ .../{ => byfilter/formula}/FormulaEntity.java | 51 +- .../modifications/ByFormulaModification.java | 307 ---------- .../AbstractModificationByAssignment.java | 368 +++++++++++ .../byfilter/ByFormulaModification.java | 111 ++++ .../byfilter/ModificationByAssignment.java | 107 ++++ .../changesets/changelog_20240912T130742Z.xml | 44 ++ .../db/changelog/db.changelog-master.yaml | 5 +- .../AbstractModificationByAssignmentTest.java | 263 ++++++++ .../BatteryModificationByAssignmentTest.java | 214 +++++++ ...GeneratorModificationByAssignmentTest.java | 441 ++++++++++++++ .../LoadModificationByAssignmentTest.java | 134 ++++ ...mpensatorModificationByAssignmentTest.java | 184 ++++++ ...ansformerModificationByAssignmentTest.java | 576 ++++++++++++++++++ ...tageLevelModificationByAssignmentTest.java | 225 +++++++ .../AbstractByFormulaModificationTest.java | 13 +- .../BatteryByFormulaModificationTest.java | 10 +- .../GeneratorByFormulaModificationTest.java | 10 +- .../LoadByFormulaModificationTest.java | 17 +- ...tCompensatorByFormulaModificationTest.java | 10 +- ...sTransformerByFormulaModificationTest.java | 10 +- ...VoltageLevelByFormulaModificationTest.java | 21 +- 50 files changed, 3580 insertions(+), 657 deletions(-) create mode 100644 src/main/java/org/gridsuite/modification/server/dto/ModificationByAssignmentInfos.java create mode 100644 src/main/java/org/gridsuite/modification/server/dto/byfilter/AbstractAssignmentInfos.java create mode 100644 src/main/java/org/gridsuite/modification/server/dto/byfilter/DataType.java create mode 100644 src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/AssignmentInfos.java create mode 100644 src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/BooleanAssignmentInfos.java create mode 100644 src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/DoubleAssignmentInfos.java create mode 100644 src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/EnumAssignmentInfos.java create mode 100644 src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/IntegerAssignmentInfos.java create mode 100644 src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/PropertyAssignmentInfos.java rename src/main/java/org/gridsuite/modification/server/dto/{formula => byfilter}/equipmentfield/BatteryField.java (79%) create mode 100644 src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/FieldUtils.java create mode 100644 src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/GeneratorField.java rename src/main/java/org/gridsuite/modification/server/dto/{formula => byfilter}/equipmentfield/LoadField.java (63%) rename src/main/java/org/gridsuite/modification/server/dto/{formula => byfilter}/equipmentfield/ShuntCompensatorField.java (71%) rename src/main/java/org/gridsuite/modification/server/dto/{formula => byfilter}/equipmentfield/TwoWindingsTransformerField.java (61%) rename src/main/java/org/gridsuite/modification/server/dto/{formula => byfilter}/equipmentfield/VoltageLevelField.java (60%) rename src/main/java/org/gridsuite/modification/server/dto/{ => byfilter}/formula/FormulaInfos.java (67%) rename src/main/java/org/gridsuite/modification/server/dto/{ => byfilter}/formula/Operator.java (87%) create mode 100644 src/main/java/org/gridsuite/modification/server/dto/byfilter/formula/ReferenceFieldOrValue.java delete mode 100644 src/main/java/org/gridsuite/modification/server/dto/formula/ReferenceFieldOrValue.java delete mode 100644 src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java create mode 100644 src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/AbstractAssignmentEntity.java rename src/main/java/org/gridsuite/modification/server/entities/equipment/modification/{ => byfilter}/ByFormulaModificationEntity.java (92%) create mode 100644 src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/ModificationByAssignmentEntity.java create mode 100644 src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/assignment/AssignmentEntity.java rename src/main/java/org/gridsuite/modification/server/entities/equipment/modification/{ => byfilter/formula}/FormulaEntity.java (64%) delete mode 100644 src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java create mode 100644 src/main/java/org/gridsuite/modification/server/modifications/byfilter/AbstractModificationByAssignment.java create mode 100644 src/main/java/org/gridsuite/modification/server/modifications/byfilter/ByFormulaModification.java create mode 100644 src/main/java/org/gridsuite/modification/server/modifications/byfilter/ModificationByAssignment.java create mode 100644 src/main/resources/db/changelog/changesets/changelog_20240912T130742Z.xml create mode 100644 src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/AbstractModificationByAssignmentTest.java create mode 100644 src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/BatteryModificationByAssignmentTest.java create mode 100644 src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/GeneratorModificationByAssignmentTest.java create mode 100644 src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/LoadModificationByAssignmentTest.java create mode 100644 src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/ShuntCompensatorModificationByAssignmentTest.java create mode 100644 src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/TwoWindingsTransformerModificationByAssignmentTest.java create mode 100644 src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/VoltageLevelModificationByAssignmentTest.java rename src/test/java/org/gridsuite/modification/server/modifications/{ => byfilter/formula}/AbstractByFormulaModificationTest.java (96%) rename src/test/java/org/gridsuite/modification/server/modifications/{ => byfilter/formula}/BatteryByFormulaModificationTest.java (96%) rename src/test/java/org/gridsuite/modification/server/modifications/{ => byfilter/formula}/GeneratorByFormulaModificationTest.java (98%) rename src/test/java/org/gridsuite/modification/server/modifications/{ => byfilter/formula}/LoadByFormulaModificationTest.java (85%) rename src/test/java/org/gridsuite/modification/server/modifications/{ => byfilter/formula}/ShuntCompensatorByFormulaModificationTest.java (96%) rename src/test/java/org/gridsuite/modification/server/modifications/{ => byfilter/formula}/TwoWindingsTransformerByFormulaModificationTest.java (98%) rename src/test/java/org/gridsuite/modification/server/modifications/{ => byfilter/formula}/VoltageLevelByFormulaModificationTest.java (94%) diff --git a/src/main/java/org/gridsuite/modification/server/ModificationType.java b/src/main/java/org/gridsuite/modification/server/ModificationType.java index 0f055ca6d..a95415d71 100644 --- a/src/main/java/org/gridsuite/modification/server/ModificationType.java +++ b/src/main/java/org/gridsuite/modification/server/ModificationType.java @@ -50,6 +50,7 @@ public enum ModificationType { TABULAR_MODIFICATION(PreloadingStrategy.COLLECTION), TABULAR_CREATION(PreloadingStrategy.COLLECTION), BY_FORMULA_MODIFICATION(PreloadingStrategy.COLLECTION), + MODIFICATION_BY_ASSIGNMENT(PreloadingStrategy.COLLECTION), COMPOSITE_MODIFICATION(PreloadingStrategy.COLLECTION); private final PreloadingStrategy strategy; diff --git a/src/main/java/org/gridsuite/modification/server/NetworkModificationException.java b/src/main/java/org/gridsuite/modification/server/NetworkModificationException.java index 530d3b4c0..493c4f654 100644 --- a/src/main/java/org/gridsuite/modification/server/NetworkModificationException.java +++ b/src/main/java/org/gridsuite/modification/server/NetworkModificationException.java @@ -113,6 +113,7 @@ public enum Type { CREATE_CONVERTER_STATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), MODIFY_CONVERTER_STATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), BY_FORMULA_MODIFICATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), + MODIFICATION_BY_ASSIGNMENT_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), HVDC_LINE_NOT_FOUND(HttpStatus.NOT_FOUND), COMPOSITE_MODIFICATION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), WRONG_HVDC_ANGLE_DROOP_ACTIVE_POWER_CONTROL(HttpStatus.BAD_REQUEST); diff --git a/src/main/java/org/gridsuite/modification/server/dto/ByFormulaModificationInfos.java b/src/main/java/org/gridsuite/modification/server/dto/ByFormulaModificationInfos.java index afa985a77..91c5c3b70 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/ByFormulaModificationInfos.java +++ b/src/main/java/org/gridsuite/modification/server/dto/ByFormulaModificationInfos.java @@ -19,9 +19,9 @@ import lombok.experimental.SuperBuilder; import org.gridsuite.modification.server.ModificationType; import org.gridsuite.modification.server.dto.annotation.ModificationErrorTypeName; -import org.gridsuite.modification.server.dto.formula.FormulaInfos; -import org.gridsuite.modification.server.entities.equipment.modification.ByFormulaModificationEntity; -import org.gridsuite.modification.server.modifications.ByFormulaModification; +import org.gridsuite.modification.server.dto.byfilter.formula.FormulaInfos; +import org.gridsuite.modification.server.entities.equipment.modification.byfilter.ByFormulaModificationEntity; +import org.gridsuite.modification.server.modifications.byfilter.ByFormulaModification; import java.util.List; @@ -57,6 +57,6 @@ public ByFormulaModification toModification() { @Override public ReportNode createSubReportNode(ReportNode reportNode) { - return reportNode.newReportNode().withMessageTemplate(ModificationType.BY_FORMULA_MODIFICATION.name(), "By formula modification").add(); + return reportNode.newReportNode().withMessageTemplate(ModificationType.BY_FORMULA_MODIFICATION.name(), "Modification by formula").add(); } } diff --git a/src/main/java/org/gridsuite/modification/server/dto/ModificationByAssignmentInfos.java b/src/main/java/org/gridsuite/modification/server/dto/ModificationByAssignmentInfos.java new file mode 100644 index 000000000..20863caee --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/ModificationByAssignmentInfos.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.dto; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.powsybl.commons.report.ReportNode; +import com.powsybl.iidm.network.IdentifiableType; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.SuperBuilder; +import org.gridsuite.modification.server.ModificationType; +import org.gridsuite.modification.server.dto.annotation.ModificationErrorTypeName; +import org.gridsuite.modification.server.dto.byfilter.assignment.AssignmentInfos; +import org.gridsuite.modification.server.entities.equipment.modification.byfilter.ModificationByAssignmentEntity; +import org.gridsuite.modification.server.modifications.byfilter.ModificationByAssignment; + +import java.util.List; + +/** + * @author Thang PHAM + */ +@SuperBuilder +@NoArgsConstructor +@Getter +@Setter +@JsonTypeName("MODIFICATION_BY_ASSIGNMENT") +@ModificationErrorTypeName("MODIFICATION_BY_ASSIGNMENT_ERROR") +@ToString(callSuper = true) +@Schema(description = "Modification by assignment") +public class ModificationByAssignmentInfos extends ModificationInfos { + @Schema(description = "Equipment type") + private IdentifiableType equipmentType; + + @Schema(description = "list of modifications") + private List> assignmentInfosList; + + @Override + public ModificationByAssignmentEntity toEntity() { + return new ModificationByAssignmentEntity(this); + } + + @Override + public ModificationByAssignment toModification() { + return new ModificationByAssignment(this); + } + + @Override + public ReportNode createSubReportNode(ReportNode reportNode) { + return reportNode.newReportNode().withMessageTemplate(ModificationType.MODIFICATION_BY_ASSIGNMENT.name(), "Modification by filter").add(); + } +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/ModificationInfos.java b/src/main/java/org/gridsuite/modification/server/dto/ModificationInfos.java index d2178532c..eb5811353 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/ModificationInfos.java +++ b/src/main/java/org/gridsuite/modification/server/dto/ModificationInfos.java @@ -68,6 +68,7 @@ @JsonSubTypes.Type(value = ConverterStationCreationInfos.class), @JsonSubTypes.Type(value = TabularModificationInfos.class), @JsonSubTypes.Type(value = ByFormulaModificationInfos.class), + @JsonSubTypes.Type(value = ModificationByAssignmentInfos.class), @JsonSubTypes.Type(value = VscModificationInfos.class), @JsonSubTypes.Type(value = ConverterStationModificationInfos.class), @JsonSubTypes.Type(value = TabularCreationInfos.class), diff --git a/src/main/java/org/gridsuite/modification/server/dto/byfilter/AbstractAssignmentInfos.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/AbstractAssignmentInfos.java new file mode 100644 index 000000000..3257c6936 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/AbstractAssignmentInfos.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; +import org.gridsuite.modification.server.dto.FilterInfos; + +import java.util.List; +import java.util.UUID; + +/** + * @author Thang PHAM + */ +@SuperBuilder +@NoArgsConstructor +@Getter +@Setter +public abstract class AbstractAssignmentInfos { + @Schema(description = "id") + private UUID id; + + @Schema(description = "List of filters") + private List filters; + + @Schema(description = "Edited field") + private String editedField; + + @JsonIgnore + public String getEditedFieldLabel() { + return editedField; + } +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/byfilter/DataType.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/DataType.java new file mode 100644 index 000000000..5ab6d5e87 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/DataType.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter; + +/** + * @author Thang PHAM + */ +public enum DataType { + ENUM, + BOOLEAN, + INTEGER, + DOUBLE, + PROPERTY +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/AssignmentInfos.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/AssignmentInfos.java new file mode 100644 index 000000000..2dd980a66 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/AssignmentInfos.java @@ -0,0 +1,54 @@ + /** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter.assignment; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; +import org.gridsuite.modification.server.dto.byfilter.AbstractAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.DataType; +import org.gridsuite.modification.server.entities.equipment.modification.byfilter.assignment.AssignmentEntity; + +/** + * @author Thang PHAM + */ +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + property = "dataType", + include = JsonTypeInfo.As.EXISTING_PROPERTY) +@JsonSubTypes({ + @JsonSubTypes.Type(value = BooleanAssignmentInfos.class, name = "BOOLEAN"), + @JsonSubTypes.Type(value = EnumAssignmentInfos.class, name = "ENUM"), + @JsonSubTypes.Type(value = DoubleAssignmentInfos.class, name = "DOUBLE"), + @JsonSubTypes.Type(value = IntegerAssignmentInfos.class, name = "INTEGER"), + @JsonSubTypes.Type(value = PropertyAssignmentInfos.class, name = "PROPERTY"), +}) +@JsonInclude(JsonInclude.Include.NON_NULL) +@SuperBuilder +@NoArgsConstructor +@Getter +@Setter +public class AssignmentInfos extends AbstractAssignmentInfos { + @Schema(description = "Value") + private T value; + + public DataType getDataType() { + throw new UnsupportedOperationException("This method should not be called"); + } + + @JsonIgnore + public AssignmentEntity toEntity() { + return new AssignmentEntity(this); + } +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/BooleanAssignmentInfos.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/BooleanAssignmentInfos.java new file mode 100644 index 000000000..d62bab7c1 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/BooleanAssignmentInfos.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter.assignment; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.gridsuite.modification.server.dto.byfilter.DataType; + +/** + * @author Thang PHAM + */ +@SuperBuilder +@NoArgsConstructor +public class BooleanAssignmentInfos extends AssignmentInfos { + @Override + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + public DataType getDataType() { + return DataType.BOOLEAN; + } +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/DoubleAssignmentInfos.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/DoubleAssignmentInfos.java new file mode 100644 index 000000000..a560ea9d4 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/DoubleAssignmentInfos.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter.assignment; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.gridsuite.modification.server.dto.byfilter.DataType; + +/** + * @author Thang PHAM + */ +@SuperBuilder +@NoArgsConstructor +public class DoubleAssignmentInfos extends AssignmentInfos { + @Override + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + public DataType getDataType() { + return DataType.DOUBLE; + } +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/EnumAssignmentInfos.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/EnumAssignmentInfos.java new file mode 100644 index 000000000..dc134c0da --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/EnumAssignmentInfos.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter.assignment; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.gridsuite.modification.server.dto.byfilter.DataType; + +/** + * @author Thang PHAM + */ +@SuperBuilder +@NoArgsConstructor +public class EnumAssignmentInfos extends AssignmentInfos { + @Override + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + public DataType getDataType() { + return DataType.ENUM; + } +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/IntegerAssignmentInfos.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/IntegerAssignmentInfos.java new file mode 100644 index 000000000..ec17e0eb4 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/IntegerAssignmentInfos.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter.assignment; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.gridsuite.modification.server.dto.byfilter.DataType; + +/** + * @author Thang PHAM + */ +@SuperBuilder +@NoArgsConstructor +public class IntegerAssignmentInfos extends AssignmentInfos { + @Override + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + public DataType getDataType() { + return DataType.INTEGER; + } +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/PropertyAssignmentInfos.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/PropertyAssignmentInfos.java new file mode 100644 index 000000000..383ed2368 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/assignment/PropertyAssignmentInfos.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter.assignment; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.gridsuite.modification.server.dto.byfilter.DataType; +import org.gridsuite.modification.server.entities.equipment.modification.byfilter.assignment.AssignmentEntity; + +/** + * @author Thang PHAM + */ +@SuperBuilder +@NoArgsConstructor +public class PropertyAssignmentInfos extends AssignmentInfos { + @Schema(description = "Property name") + @Getter + private String propertyName; + + @Override + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + public DataType getDataType() { + return DataType.PROPERTY; + } + + @JsonIgnore + @Override + public String getEditedFieldLabel() { + return propertyName + " " + super.getEditedFieldLabel(); + } + + @Override + public AssignmentEntity toEntity() { + AssignmentEntity assignmentEntity = super.toEntity(); + assignmentEntity.setPropertyName(propertyName); + return assignmentEntity; + } +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/BatteryField.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/BatteryField.java similarity index 79% rename from src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/BatteryField.java rename to src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/BatteryField.java index 7c82638e7..117db9718 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/BatteryField.java +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/BatteryField.java @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.dto.formula.equipmentfield; +package org.gridsuite.modification.server.dto.byfilter.equipmentfield; import com.powsybl.iidm.network.Battery; import com.powsybl.iidm.network.extensions.ActivePowerControl; @@ -30,21 +30,21 @@ public enum BatteryField { REACTIVE_POWER_SET_POINT, DROOP; - public static Double getReferenceValue(Battery battery, String batteryField) { + public static String getReferenceValue(Battery battery, String batteryField) { ActivePowerControl activePowerControl = battery.getExtension(ActivePowerControl.class); BatteryField field = BatteryField.valueOf(batteryField); return switch (field) { - case MINIMUM_ACTIVE_POWER -> battery.getMinP(); - case MAXIMUM_ACTIVE_POWER -> battery.getMaxP(); - case ACTIVE_POWER_SET_POINT -> battery.getTargetP(); - case REACTIVE_POWER_SET_POINT -> battery.getTargetQ(); - case DROOP -> activePowerControl != null ? activePowerControl.getDroop() : null; + case MINIMUM_ACTIVE_POWER -> String.valueOf(battery.getMinP()); + case MAXIMUM_ACTIVE_POWER -> String.valueOf(battery.getMaxP()); + case ACTIVE_POWER_SET_POINT -> String.valueOf(battery.getTargetP()); + case REACTIVE_POWER_SET_POINT -> String.valueOf(battery.getTargetQ()); + case DROOP -> activePowerControl != null ? String.valueOf(activePowerControl.getDroop()) : null; }; } - public static void setNewValue(Battery battery, String batteryField, @NotNull Double newValue) { + public static void setNewValue(Battery battery, String batteryField, @NotNull String newValue) { BatteryField field = BatteryField.valueOf(batteryField); - final AttributeModification attributeModification = new AttributeModification<>(newValue, OperationType.SET); + final AttributeModification attributeModification = new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET); switch (field) { case MINIMUM_ACTIVE_POWER -> modifyBatteryActiveLimitsAttributes(null, attributeModification, battery, null); @@ -64,7 +64,7 @@ public static void setNewValue(Battery battery, String batteryField, @NotNull Do ActivePowerControlAdder activePowerControlAdder = battery.newExtension(ActivePowerControlAdder.class); ModificationUtils.getInstance().modifyActivePowerControlAttributes( activePowerControl, activePowerControlAdder, null, - new AttributeModification<>(newValue.floatValue(), OperationType.SET), null, null); + new AttributeModification<>(Float.parseFloat(newValue), OperationType.SET), null, null); } } } diff --git a/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/FieldUtils.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/FieldUtils.java new file mode 100644 index 000000000..66e924caf --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/FieldUtils.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter.equipmentfield; + +import com.powsybl.iidm.network.*; +import org.gridsuite.modification.server.NetworkModificationException; + +import javax.annotation.Nullable; + +/** + * @author Thang PHAM + */ +public final class FieldUtils { + + private FieldUtils() { + + } + + @Nullable + public static String getFieldValue(Identifiable equipment, String equipmentField) { + return switch (equipment.getType()) { + case GENERATOR -> GeneratorField.getReferenceValue((Generator) equipment, equipmentField); + case BATTERY -> BatteryField.getReferenceValue((Battery) equipment, equipmentField); + case SHUNT_COMPENSATOR -> + ShuntCompensatorField.getReferenceValue((ShuntCompensator) equipment, equipmentField); + case VOLTAGE_LEVEL -> VoltageLevelField.getReferenceValue((VoltageLevel) equipment, equipmentField); + case LOAD -> LoadField.getReferenceValue((Load) equipment, equipmentField); + case TWO_WINDINGS_TRANSFORMER -> + TwoWindingsTransformerField.getReferenceValue((TwoWindingsTransformer) equipment, equipmentField); + default -> throw new NetworkModificationException(NetworkModificationException.Type.MODIFICATION_ERROR, + "Unsupported getting value for equipment type : " + equipment.getType().name()); + }; + } + + public static void setFieldValue(Identifiable equipment, String equipmentField, String newValue) { + switch (equipment.getType()) { + case GENERATOR -> GeneratorField.setNewValue((Generator) equipment, equipmentField, newValue); + case BATTERY -> BatteryField.setNewValue((Battery) equipment, equipmentField, newValue); + case SHUNT_COMPENSATOR -> ShuntCompensatorField.setNewValue((ShuntCompensator) equipment, equipmentField, newValue); + case VOLTAGE_LEVEL -> VoltageLevelField.setNewValue((VoltageLevel) equipment, equipmentField, newValue); + case LOAD -> LoadField.setNewValue((Load) equipment, equipmentField, newValue); + case TWO_WINDINGS_TRANSFORMER -> TwoWindingsTransformerField.setNewValue((TwoWindingsTransformer) equipment, equipmentField, newValue); + default -> throw new NetworkModificationException(NetworkModificationException.Type.MODIFICATION_ERROR, + "Unsupported setting value for equipment type : " + equipment.getType().name()); + } + } +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/GeneratorField.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/GeneratorField.java new file mode 100644 index 000000000..028c313f4 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/GeneratorField.java @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2023, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter.equipmentfield; + +import com.powsybl.iidm.network.Generator; +import com.powsybl.iidm.network.extensions.*; +import com.powsybl.network.store.iidm.impl.extensions.CoordinatedReactiveControlAdderImpl; +import jakarta.validation.constraints.NotNull; +import org.gridsuite.modification.server.dto.AttributeModification; +import org.gridsuite.modification.server.dto.OperationType; +import org.gridsuite.modification.server.modifications.ModificationUtils; + +import static org.gridsuite.modification.server.NetworkModificationException.Type.MODIFY_GENERATOR_ERROR; +import static org.gridsuite.modification.server.modifications.GeneratorModification.*; + +/** + * @author Seddik Yengui + */ +public enum GeneratorField { + VOLTAGE_REGULATOR_ON, + MINIMUM_ACTIVE_POWER, + MAXIMUM_ACTIVE_POWER, + RATED_NOMINAL_POWER, + ACTIVE_POWER_SET_POINT, + REACTIVE_POWER_SET_POINT, + VOLTAGE_SET_POINT, + PLANNED_ACTIVE_POWER_SET_POINT, + MARGINAL_COST, + PLANNED_OUTAGE_RATE, + FORCED_OUTAGE_RATE, + DROOP, + TRANSIENT_REACTANCE, + STEP_UP_TRANSFORMER_REACTANCE, + Q_PERCENT; + + public static String getReferenceValue(Generator generator, String generatorField) { + ActivePowerControl activePowerControl = generator.getExtension(ActivePowerControl.class); + GeneratorStartup generatorStartup = generator.getExtension(GeneratorStartup.class); + GeneratorShortCircuit generatorShortCircuit = generator.getExtension(GeneratorShortCircuit.class); + CoordinatedReactiveControl coordinatedReactiveControl = generator.getExtension(CoordinatedReactiveControl.class); + GeneratorField field = GeneratorField.valueOf(generatorField); + return switch (field) { + case VOLTAGE_REGULATOR_ON -> String.valueOf(generator.isVoltageRegulatorOn()); + case MAXIMUM_ACTIVE_POWER -> String.valueOf(generator.getMaxP()); + case MINIMUM_ACTIVE_POWER -> String.valueOf(generator.getMinP()); + case ACTIVE_POWER_SET_POINT -> String.valueOf(generator.getTargetP()); + case RATED_NOMINAL_POWER -> String.valueOf(generator.getRatedS()); + case REACTIVE_POWER_SET_POINT -> String.valueOf(generator.getTargetQ()); + case VOLTAGE_SET_POINT -> String.valueOf(generator.getTargetV()); + case PLANNED_ACTIVE_POWER_SET_POINT -> generatorStartup != null ? String.valueOf(generatorStartup.getPlannedActivePowerSetpoint()) : null; + case MARGINAL_COST -> generatorStartup != null ? String.valueOf(generatorStartup.getMarginalCost()) : null; + case PLANNED_OUTAGE_RATE -> generatorStartup != null ? String.valueOf(generatorStartup.getPlannedOutageRate()) : null; + case FORCED_OUTAGE_RATE -> generatorStartup != null ? String.valueOf(generatorStartup.getForcedOutageRate()) : null; + case DROOP -> activePowerControl != null ? String.valueOf(activePowerControl.getDroop()) : null; + case TRANSIENT_REACTANCE -> generatorShortCircuit != null ? String.valueOf(generatorShortCircuit.getDirectTransX()) : null; + case STEP_UP_TRANSFORMER_REACTANCE -> generatorShortCircuit != null ? String.valueOf(generatorShortCircuit.getStepUpTransformerX()) : null; + case Q_PERCENT -> coordinatedReactiveControl != null ? String.valueOf(coordinatedReactiveControl.getQPercent()) : null; + }; + } + + public static void setNewValue(Generator generator, String generatorField, @NotNull String newValue) { + GeneratorField field = GeneratorField.valueOf(generatorField); + switch (field) { + case MAXIMUM_ACTIVE_POWER -> modifyGeneratorActiveLimitsAttributes( + new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), + null, null, generator, null); + case MINIMUM_ACTIVE_POWER -> modifyGeneratorActiveLimitsAttributes( + null, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), null, generator, null); + case ACTIVE_POWER_SET_POINT -> { + ModificationUtils.getInstance().checkActivePowerZeroOrBetweenMinAndMaxActivePower( + new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), + null, null, generator.getMinP(), generator.getMaxP(), generator.getTargetP(), + MODIFY_GENERATOR_ERROR, "Generator '" + generator.getId() + "' : " + ); + generator.setTargetP(Double.parseDouble(newValue)); + } + case RATED_NOMINAL_POWER -> modifyGeneratorActiveLimitsAttributes( + null, null, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), generator, null); + case REACTIVE_POWER_SET_POINT -> modifyTargetQ(generator, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET)); + case VOLTAGE_SET_POINT -> modifyTargetV(generator, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET)); + case PLANNED_ACTIVE_POWER_SET_POINT -> modifyGeneratorStartUpAttributes( + new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), null, + null, null, generator, null, null); + case MARGINAL_COST -> modifyGeneratorStartUpAttributes( + null, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), + null, null, generator, null, null); + case PLANNED_OUTAGE_RATE -> modifyGeneratorStartUpAttributes( + null, null, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), + null, generator, null, null); + case FORCED_OUTAGE_RATE -> + modifyGeneratorStartUpAttributes(null, null, null, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), generator, null, null); + case DROOP -> { + ActivePowerControl activePowerControl = generator.getExtension(ActivePowerControl.class); + ActivePowerControlAdder activePowerControlAdder = generator.newExtension(ActivePowerControlAdder.class); + ModificationUtils.getInstance().modifyActivePowerControlAttributes(activePowerControl, activePowerControlAdder, null, + new AttributeModification<>(Float.parseFloat(newValue), OperationType.SET), null, null); + } + case TRANSIENT_REACTANCE -> modifyGeneratorShortCircuitAttributes( + new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), + null, generator, null); + case STEP_UP_TRANSFORMER_REACTANCE -> modifyGeneratorShortCircuitAttributes( + null, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), generator, null); + case Q_PERCENT -> generator.newExtension(CoordinatedReactiveControlAdderImpl.class) + .withQPercent(Double.parseDouble(newValue)) + .add(); + case VOLTAGE_REGULATOR_ON -> generator.setVoltageRegulatorOn(Boolean.parseBoolean(newValue)); + } + } +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/LoadField.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/LoadField.java similarity index 63% rename from src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/LoadField.java rename to src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/LoadField.java index 8c01d3f96..b0d52a427 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/LoadField.java +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/LoadField.java @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.dto.formula.equipmentfield; +package org.gridsuite.modification.server.dto.byfilter.equipmentfield; import com.powsybl.iidm.network.Load; import org.gridsuite.modification.server.dto.AttributeModification; @@ -13,28 +13,32 @@ import static org.gridsuite.modification.server.modifications.LoadModification.modifyP0; import static org.gridsuite.modification.server.modifications.LoadModification.modifyQ0; +import com.powsybl.iidm.network.LoadType; +import jakarta.validation.constraints.NotNull; /** * @author Seddik Yengui */ - public enum LoadField { + LOAD_TYPE, ACTIVE_POWER, REACTIVE_POWER; - public static Double getReferenceValue(Load load, String loadField) { + public static String getReferenceValue(Load load, String loadField) { LoadField field = LoadField.valueOf(loadField); return switch (field) { - case ACTIVE_POWER -> load.getP0(); - case REACTIVE_POWER -> load.getQ0(); + case LOAD_TYPE -> load.getLoadType().name(); + case ACTIVE_POWER -> String.valueOf(load.getP0()); + case REACTIVE_POWER -> String.valueOf(load.getQ0()); }; } - public static void setNewValue(Load load, String loadField, Double newValue) { + public static void setNewValue(Load load, String loadField, @NotNull String newValue) { LoadField field = LoadField.valueOf(loadField); switch (field) { - case ACTIVE_POWER -> modifyP0(load, new AttributeModification<>(newValue, OperationType.SET), null); - case REACTIVE_POWER -> modifyQ0(load, new AttributeModification<>(newValue, OperationType.SET), null); + case LOAD_TYPE -> load.setLoadType(LoadType.valueOf(newValue)); + case ACTIVE_POWER -> modifyP0(load, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), null); + case REACTIVE_POWER -> modifyQ0(load, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), null); } } } diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/ShuntCompensatorField.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/ShuntCompensatorField.java similarity index 71% rename from src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/ShuntCompensatorField.java rename to src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/ShuntCompensatorField.java index 87dabb14a..1f97de712 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/ShuntCompensatorField.java +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/ShuntCompensatorField.java @@ -5,12 +5,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.dto.formula.equipmentfield; +package org.gridsuite.modification.server.dto.byfilter.equipmentfield; import com.powsybl.iidm.network.ShuntCompensator; import com.powsybl.iidm.network.ShuntCompensatorLinearModel; import com.powsybl.iidm.network.ShuntCompensatorModelType; import com.powsybl.iidm.network.VoltageLevel; +import jakarta.validation.constraints.NotNull; import org.gridsuite.modification.server.NetworkModificationException; import org.gridsuite.modification.server.dto.AttributeModification; import org.gridsuite.modification.server.dto.OperationType; @@ -21,25 +22,24 @@ /** * @author Seddik Yengui */ - public enum ShuntCompensatorField { MAXIMUM_SECTION_COUNT, SECTION_COUNT, MAXIMUM_SUSCEPTANCE, MAXIMUM_Q_AT_NOMINAL_VOLTAGE; - public static Double getReferenceValue(ShuntCompensator shuntCompensator, String shuntCompensatorField) { + public static String getReferenceValue(ShuntCompensator shuntCompensator, String shuntCompensatorField) { VoltageLevel voltageLevel = shuntCompensator.getTerminal().getVoltageLevel(); ShuntCompensatorField field = ShuntCompensatorField.valueOf(shuntCompensatorField); return switch (field) { - case MAXIMUM_SECTION_COUNT -> (double) shuntCompensator.getMaximumSectionCount(); - case SECTION_COUNT -> (double) shuntCompensator.getSectionCount(); - case MAXIMUM_SUSCEPTANCE -> shuntCompensator.getB() * shuntCompensator.getMaximumSectionCount(); - case MAXIMUM_Q_AT_NOMINAL_VOLTAGE -> Math.abs(Math.pow(voltageLevel.getNominalV(), 2) * shuntCompensator.getB()) * shuntCompensator.getMaximumSectionCount(); + case MAXIMUM_SECTION_COUNT -> String.valueOf(shuntCompensator.getMaximumSectionCount()); + case SECTION_COUNT -> String.valueOf(shuntCompensator.getSectionCount()); + case MAXIMUM_SUSCEPTANCE -> String.valueOf(shuntCompensator.getB() * shuntCompensator.getMaximumSectionCount()); + case MAXIMUM_Q_AT_NOMINAL_VOLTAGE -> String.valueOf(Math.abs(Math.pow(voltageLevel.getNominalV(), 2) * shuntCompensator.getB()) * shuntCompensator.getMaximumSectionCount()); }; } - public static void setNewValue(ShuntCompensator shuntCompensator, String shuntCompensatorField, Double newValue) { + public static void setNewValue(ShuntCompensator shuntCompensator, String shuntCompensatorField, @NotNull String newValue) { if (shuntCompensator.getModelType() != ShuntCompensatorModelType.LINEAR) { throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, String.format("Shunt compensator with %s model is not supported", shuntCompensator.getModelType())); @@ -52,12 +52,12 @@ public static void setNewValue(ShuntCompensator shuntCompensator, String shuntCo shuntCompensatorType = ShuntCompensatorType.CAPACITOR; } switch (field) { - case MAXIMUM_SECTION_COUNT -> modifyMaximumSectionCount(new AttributeModification<>(newValue.intValue(), OperationType.SET), + case MAXIMUM_SECTION_COUNT -> modifyMaximumSectionCount(new AttributeModification<>((int) Double.parseDouble(newValue), OperationType.SET), null, null, null, shuntCompensator, model); - case SECTION_COUNT -> modifySectionCount(new AttributeModification<>(newValue.intValue(), OperationType.SET), null, shuntCompensator); - case MAXIMUM_SUSCEPTANCE -> modifyMaxSusceptance(new AttributeModification<>(newValue, OperationType.SET), + case SECTION_COUNT -> modifySectionCount(new AttributeModification<>((int) Double.parseDouble(newValue), OperationType.SET), null, shuntCompensator); + case MAXIMUM_SUSCEPTANCE -> modifyMaxSusceptance(new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), shuntCompensator.getMaximumSectionCount(), null, model); - case MAXIMUM_Q_AT_NOMINAL_VOLTAGE -> modifyMaximumQAtNominalVoltage(new AttributeModification<>(newValue, OperationType.SET), + case MAXIMUM_Q_AT_NOMINAL_VOLTAGE -> modifyMaximumQAtNominalVoltage(new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), voltageLevel, shuntCompensator.getMaximumSectionCount(), null, model, shuntCompensatorType); } } diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/TwoWindingsTransformerField.java similarity index 61% rename from src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java rename to src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/TwoWindingsTransformerField.java index 6a13e93d6..78d35d9bd 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/TwoWindingsTransformerField.java @@ -1,12 +1,24 @@ -package org.gridsuite.modification.server.dto.formula.equipmentfield; +/** + * Copyright (c) 2023, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter.equipmentfield; import com.powsybl.iidm.network.PhaseTapChanger; import com.powsybl.iidm.network.RatioTapChanger; import com.powsybl.iidm.network.TwoWindingsTransformer; +import jakarta.validation.constraints.NotNull; import org.gridsuite.modification.server.dto.AttributeModification; import org.gridsuite.modification.server.dto.OperationType; + import static org.gridsuite.modification.server.modifications.TwoWindingsTransformerModification.*; +/** + * @author Seddik Yengui + */ public enum TwoWindingsTransformerField { R, X, @@ -24,35 +36,35 @@ public enum TwoWindingsTransformerField { PHASE_TAP_POSITION, PHASE_TARGET_DEADBAND; - public static Double getReferenceValue(TwoWindingsTransformer transformer, String twoWindingsTransformerField) { + public static String getReferenceValue(TwoWindingsTransformer transformer, String twoWindingsTransformerField) { TwoWindingsTransformerField field = TwoWindingsTransformerField.valueOf(twoWindingsTransformerField); final PhaseTapChanger phaseTapChanger = transformer.getPhaseTapChanger(); final RatioTapChanger ratioTapChanger = transformer.getRatioTapChanger(); return switch (field) { - case R -> transformer.getR(); - case X -> transformer.getX(); - case G -> transformer.getG(); - case B -> transformer.getB(); - case RATED_U1 -> transformer.getRatedU1(); - case RATED_U2 -> transformer.getRatedU2(); - case RATED_S -> transformer.getRatedS(); - case TARGET_V -> ratioTapChanger != null ? ratioTapChanger.getTargetV() : null; - case RATIO_LOW_TAP_POSITION -> ratioTapChanger != null ? (double) ratioTapChanger.getLowTapPosition() : null; - case RATIO_TAP_POSITION -> ratioTapChanger != null ? (double) ratioTapChanger.getTapPosition() : null; - case RATIO_TARGET_DEADBAND -> ratioTapChanger != null ? ratioTapChanger.getTargetDeadband() : null; - case REGULATION_VALUE -> phaseTapChanger != null ? phaseTapChanger.getRegulationValue() : null; - case PHASE_LOW_TAP_POSITION -> phaseTapChanger != null ? (double) phaseTapChanger.getLowTapPosition() : null; - case PHASE_TAP_POSITION -> phaseTapChanger != null ? (double) phaseTapChanger.getTapPosition() : null; - case PHASE_TARGET_DEADBAND -> phaseTapChanger != null ? phaseTapChanger.getTargetDeadband() : null; + case R -> String.valueOf(transformer.getR()); + case X -> String.valueOf(transformer.getX()); + case G -> String.valueOf(transformer.getG()); + case B -> String.valueOf(transformer.getB()); + case RATED_U1 -> String.valueOf(transformer.getRatedU1()); + case RATED_U2 -> String.valueOf(transformer.getRatedU2()); + case RATED_S -> String.valueOf(transformer.getRatedS()); + case TARGET_V -> ratioTapChanger != null ? String.valueOf(ratioTapChanger.getTargetV()) : null; + case RATIO_LOW_TAP_POSITION -> ratioTapChanger != null ? String.valueOf(ratioTapChanger.getLowTapPosition()) : null; + case RATIO_TAP_POSITION -> ratioTapChanger != null ? String.valueOf(ratioTapChanger.getTapPosition()) : null; + case RATIO_TARGET_DEADBAND -> ratioTapChanger != null ? String.valueOf(ratioTapChanger.getTargetDeadband()) : null; + case REGULATION_VALUE -> phaseTapChanger != null ? String.valueOf(phaseTapChanger.getRegulationValue()) : null; + case PHASE_LOW_TAP_POSITION -> phaseTapChanger != null ? String.valueOf(phaseTapChanger.getLowTapPosition()) : null; + case PHASE_TAP_POSITION -> phaseTapChanger != null ? String.valueOf(phaseTapChanger.getTapPosition()) : null; + case PHASE_TARGET_DEADBAND -> phaseTapChanger != null ? String.valueOf(phaseTapChanger.getTargetDeadband()) : null; }; } - public static void setNewValue(TwoWindingsTransformer transformer, String twoWindingsTransformerField, Double newValue) { + public static void setNewValue(TwoWindingsTransformer transformer, String twoWindingsTransformerField, @NotNull String newValue) { TwoWindingsTransformerField field = TwoWindingsTransformerField.valueOf(twoWindingsTransformerField); final PhaseTapChanger phaseTapChanger = transformer.getPhaseTapChanger(); final RatioTapChanger ratioTapChanger = transformer.getRatioTapChanger(); final PhaseTapChanger.RegulationMode regulationMode = phaseTapChanger != null ? phaseTapChanger.getRegulationMode() : null; - final AttributeModification attributeModification = new AttributeModification<>(newValue, OperationType.SET); + final AttributeModification attributeModification = new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET); switch (field) { case R -> modifyR(transformer, attributeModification, null); @@ -64,17 +76,16 @@ public static void setNewValue(TwoWindingsTransformer transformer, String twoWin case RATED_S -> modifyRatedS(transformer, attributeModification, null); case TARGET_V -> modifyTargets(ratioTapChanger, null, true, attributeModification, null, null); case RATIO_LOW_TAP_POSITION -> processTapChangerPositionsAndSteps(ratioTapChanger, null, true, - new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null, null); + new AttributeModification<>((int) Double.parseDouble(newValue), OperationType.SET), null, null, null); case RATIO_TAP_POSITION -> processTapChangerPositionsAndSteps(ratioTapChanger, null, true, - null, new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null); + null, new AttributeModification<>((int) Double.parseDouble(newValue), OperationType.SET), null, null); case RATIO_TARGET_DEADBAND -> modifyTargets(ratioTapChanger, null, true, null, attributeModification, null); case REGULATION_VALUE -> processPhaseTapRegulation( - phaseTapChanger, null, regulationMode, true, attributeModification, null, null - ); + phaseTapChanger, null, regulationMode, true, attributeModification, null, null); case PHASE_LOW_TAP_POSITION -> processTapChangerPositionsAndSteps(phaseTapChanger, null, true, - new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null, null); + new AttributeModification<>((int) Double.parseDouble(newValue), OperationType.SET), null, null, null); case PHASE_TAP_POSITION -> processTapChangerPositionsAndSteps(phaseTapChanger, null, true, - null, new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null); + null, new AttributeModification<>((int) Double.parseDouble(newValue), OperationType.SET), null, null); case PHASE_TARGET_DEADBAND -> processPhaseTapRegulation( phaseTapChanger, null, null, true, null, attributeModification, null ); diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/VoltageLevelField.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/VoltageLevelField.java similarity index 60% rename from src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/VoltageLevelField.java rename to src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/VoltageLevelField.java index 69f366ad4..ee01ff24c 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/VoltageLevelField.java +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/equipmentfield/VoltageLevelField.java @@ -5,10 +5,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.dto.formula.equipmentfield; +package org.gridsuite.modification.server.dto.byfilter.equipmentfield; import com.powsybl.iidm.network.VoltageLevel; import com.powsybl.iidm.network.extensions.IdentifiableShortCircuit; +import jakarta.validation.constraints.NotNull; import org.gridsuite.modification.server.dto.AttributeModification; import org.gridsuite.modification.server.dto.OperationType; @@ -17,7 +18,6 @@ /** * @author Seddik Yengui */ - public enum VoltageLevelField { NOMINAL_VOLTAGE, LOW_VOLTAGE_LIMIT, @@ -25,28 +25,28 @@ public enum VoltageLevelField { LOW_SHORT_CIRCUIT_CURRENT_LIMIT, HIGH_SHORT_CIRCUIT_CURRENT_LIMIT; - public static Double getReferenceValue(VoltageLevel voltageLevel, String voltageLevelField) { + public static String getReferenceValue(VoltageLevel voltageLevel, String voltageLevelField) { IdentifiableShortCircuit identifiableShortCircuit = voltageLevel.getExtension(IdentifiableShortCircuit.class); VoltageLevelField field = VoltageLevelField.valueOf(voltageLevelField); return switch (field) { - case NOMINAL_VOLTAGE -> voltageLevel.getNominalV(); - case LOW_VOLTAGE_LIMIT -> voltageLevel.getLowVoltageLimit(); - case HIGH_VOLTAGE_LIMIT -> voltageLevel.getHighVoltageLimit(); - case LOW_SHORT_CIRCUIT_CURRENT_LIMIT -> identifiableShortCircuit == null ? null : identifiableShortCircuit.getIpMin(); - case HIGH_SHORT_CIRCUIT_CURRENT_LIMIT -> identifiableShortCircuit == null ? null : identifiableShortCircuit.getIpMax(); + case NOMINAL_VOLTAGE -> String.valueOf(voltageLevel.getNominalV()); + case LOW_VOLTAGE_LIMIT -> String.valueOf(voltageLevel.getLowVoltageLimit()); + case HIGH_VOLTAGE_LIMIT -> String.valueOf(voltageLevel.getHighVoltageLimit()); + case LOW_SHORT_CIRCUIT_CURRENT_LIMIT -> identifiableShortCircuit != null ? String.valueOf(identifiableShortCircuit.getIpMin()) : null; + case HIGH_SHORT_CIRCUIT_CURRENT_LIMIT -> identifiableShortCircuit != null ? String.valueOf(identifiableShortCircuit.getIpMax()) : null; }; } - public static void setNewValue(VoltageLevel voltageLevel, String voltageLevelField, Double newValue) { + public static void setNewValue(VoltageLevel voltageLevel, String voltageLevelField, @NotNull String newValue) { VoltageLevelField field = VoltageLevelField.valueOf(voltageLevelField); switch (field) { - case NOMINAL_VOLTAGE -> modifyNominalV(voltageLevel, new AttributeModification<>(newValue, OperationType.SET), null); - case LOW_VOLTAGE_LIMIT -> modifLowVoltageLimit(voltageLevel, new AttributeModification<>(newValue, OperationType.SET), null); - case HIGH_VOLTAGE_LIMIT -> modifyHighVoltageLimit(voltageLevel, new AttributeModification<>(newValue, OperationType.SET), null); + case NOMINAL_VOLTAGE -> modifyNominalV(voltageLevel, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), null); + case LOW_VOLTAGE_LIMIT -> modifLowVoltageLimit(voltageLevel, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), null); + case HIGH_VOLTAGE_LIMIT -> modifyHighVoltageLimit(voltageLevel, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), null); case LOW_SHORT_CIRCUIT_CURRENT_LIMIT -> modifyVoltageLevelShortCircuit( - new AttributeModification<>(newValue, OperationType.SET), null, null, voltageLevel); + new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), null, null, voltageLevel); case HIGH_SHORT_CIRCUIT_CURRENT_LIMIT -> modifyVoltageLevelShortCircuit( - null, new AttributeModification<>(newValue, OperationType.SET), null, voltageLevel); + null, new AttributeModification<>(Double.parseDouble(newValue), OperationType.SET), null, voltageLevel); } } } diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/FormulaInfos.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/formula/FormulaInfos.java similarity index 67% rename from src/main/java/org/gridsuite/modification/server/dto/formula/FormulaInfos.java rename to src/main/java/org/gridsuite/modification/server/dto/byfilter/formula/FormulaInfos.java index 736556a4d..663191c4e 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/FormulaInfos.java +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/formula/FormulaInfos.java @@ -5,19 +5,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.dto.formula; +package org.gridsuite.modification.server.dto.byfilter.formula; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.experimental.SuperBuilder; -import org.gridsuite.modification.server.dto.FilterInfos; -import org.gridsuite.modification.server.entities.equipment.modification.FormulaEntity; - -import java.util.List; -import java.util.UUID; +import org.gridsuite.modification.server.dto.byfilter.AbstractAssignmentInfos; +import org.gridsuite.modification.server.entities.equipment.modification.byfilter.formula.FormulaEntity; /** * @author Seddik Yengui @@ -25,18 +21,9 @@ @SuperBuilder @NoArgsConstructor -@AllArgsConstructor @Getter @Setter -public class FormulaInfos { - @Schema(description = "id") - private UUID id; - - @Schema(description = "List of filters") - private List filters; - - @Schema(description = "Edited field") - private String editedField; +public class FormulaInfos extends AbstractAssignmentInfos { @Schema(description = "First reference field or value") private ReferenceFieldOrValue fieldOrValue1; diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/Operator.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/formula/Operator.java similarity index 87% rename from src/main/java/org/gridsuite/modification/server/dto/formula/Operator.java rename to src/main/java/org/gridsuite/modification/server/dto/byfilter/formula/Operator.java index d00f5e65d..df134ec57 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/Operator.java +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/formula/Operator.java @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.dto.formula; +package org.gridsuite.modification.server.dto.byfilter.formula; /** * @author Seddik Yengui diff --git a/src/main/java/org/gridsuite/modification/server/dto/byfilter/formula/ReferenceFieldOrValue.java b/src/main/java/org/gridsuite/modification/server/dto/byfilter/formula/ReferenceFieldOrValue.java new file mode 100644 index 000000000..1967b81dd --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/byfilter/formula/ReferenceFieldOrValue.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2023, 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/. + */ + +package org.gridsuite.modification.server.dto.byfilter.formula; + +import com.powsybl.iidm.network.Identifiable; +import lombok.*; +import org.gridsuite.modification.server.NetworkModificationException; + +import static org.gridsuite.modification.server.dto.byfilter.equipmentfield.FieldUtils.getFieldValue; + + +/** + * @author Seddik Yengui + */ + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class ReferenceFieldOrValue { + private String equipmentField; + + private Double value; + + public Double getRefOrValue(Identifiable identifiable) { + if (value == null && equipmentField == null) { + throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, + "There is no value or reference to any of the equipment fields"); + } + + if (value != null && !Double.isNaN(value)) { + return value; + } + + String referenceValue = getFieldValue(identifiable, equipmentField); + + if (referenceValue == null) { + return Double.NaN; + } + + return Double.parseDouble(referenceValue); + } + +} diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/ReferenceFieldOrValue.java b/src/main/java/org/gridsuite/modification/server/dto/formula/ReferenceFieldOrValue.java deleted file mode 100644 index aaae6b502..000000000 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/ReferenceFieldOrValue.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright (c) 2023, 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/. - */ - -package org.gridsuite.modification.server.dto.formula; - -import com.powsybl.iidm.network.Battery; -import com.powsybl.iidm.network.Generator; -import com.powsybl.iidm.network.Identifiable; -import com.powsybl.iidm.network.IdentifiableType; -import com.powsybl.iidm.network.Load; -import com.powsybl.iidm.network.ShuntCompensator; -import com.powsybl.iidm.network.TwoWindingsTransformer; -import com.powsybl.iidm.network.VoltageLevel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.gridsuite.modification.server.NetworkModificationException; -import org.gridsuite.modification.server.dto.formula.equipmentfield.BatteryField; -import org.gridsuite.modification.server.dto.formula.equipmentfield.GeneratorField; -import org.gridsuite.modification.server.dto.formula.equipmentfield.LoadField; -import org.gridsuite.modification.server.dto.formula.equipmentfield.ShuntCompensatorField; -import org.gridsuite.modification.server.dto.formula.equipmentfield.TwoWindingsTransformerField; -import org.gridsuite.modification.server.dto.formula.equipmentfield.VoltageLevelField; - - -/** - * @author Seddik Yengui - */ - -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -public class ReferenceFieldOrValue { - private String equipmentField; - - private Double value; - - public Double getRefOrValue(Identifiable identifiable) { - if (value == null && equipmentField == null) { - throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, - "There is no value or reference to any of the equipment fields"); - } - - if (value != null && !Double.isNaN(value)) { - return value; - } - - IdentifiableType identifiableType = identifiable.getType(); - return switch (identifiableType) { - case GENERATOR -> GeneratorField.getReferenceValue((Generator) identifiable, equipmentField); - case BATTERY -> BatteryField.getReferenceValue((Battery) identifiable, equipmentField); - case SHUNT_COMPENSATOR -> ShuntCompensatorField.getReferenceValue((ShuntCompensator) identifiable, equipmentField); - case VOLTAGE_LEVEL -> VoltageLevelField.getReferenceValue((VoltageLevel) identifiable, equipmentField); - case LOAD -> LoadField.getReferenceValue((Load) identifiable, equipmentField); - case TWO_WINDINGS_TRANSFORMER -> TwoWindingsTransformerField.getReferenceValue((TwoWindingsTransformer) identifiable, equipmentField); - default -> throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, - String.format("Unsupported equipment type : %s", identifiableType.name())); - }; - } -} diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java deleted file mode 100644 index d36390c58..000000000 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright (c) 2023, 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/. - */ - -package org.gridsuite.modification.server.dto.formula.equipmentfield; - -import com.powsybl.iidm.network.Generator; -import com.powsybl.iidm.network.extensions.ActivePowerControl; -import com.powsybl.iidm.network.extensions.ActivePowerControlAdder; -import com.powsybl.iidm.network.extensions.CoordinatedReactiveControl; -import com.powsybl.iidm.network.extensions.GeneratorShortCircuit; -import com.powsybl.iidm.network.extensions.GeneratorStartup; -import com.powsybl.network.store.iidm.impl.extensions.CoordinatedReactiveControlAdderImpl; -import org.gridsuite.modification.server.dto.AttributeModification; -import org.gridsuite.modification.server.dto.OperationType; -import org.gridsuite.modification.server.modifications.ModificationUtils; - -import static org.gridsuite.modification.server.NetworkModificationException.Type.MODIFY_GENERATOR_ERROR; -import static org.gridsuite.modification.server.modifications.GeneratorModification.*; - -/** - * @author Seddik Yengui - */ - -public enum GeneratorField { - MINIMUM_ACTIVE_POWER, - MAXIMUM_ACTIVE_POWER, - RATED_NOMINAL_POWER, - ACTIVE_POWER_SET_POINT, - REACTIVE_POWER_SET_POINT, - VOLTAGE_SET_POINT, - PLANNED_ACTIVE_POWER_SET_POINT, - MARGINAL_COST, - PLANNED_OUTAGE_RATE, - FORCED_OUTAGE_RATE, - DROOP, - TRANSIENT_REACTANCE, - STEP_UP_TRANSFORMER_REACTANCE, - Q_PERCENT; - - public static Double getReferenceValue(Generator generator, String generatorField) { - ActivePowerControl activePowerControl = generator.getExtension(ActivePowerControl.class); - GeneratorStartup generatorStartup = generator.getExtension(GeneratorStartup.class); - GeneratorShortCircuit generatorShortCircuit = generator.getExtension(GeneratorShortCircuit.class); - CoordinatedReactiveControl coordinatedReactiveControl = generator.getExtension(CoordinatedReactiveControl.class); - GeneratorField field = GeneratorField.valueOf(generatorField); - return switch (field) { - case MAXIMUM_ACTIVE_POWER -> generator.getMaxP(); - case MINIMUM_ACTIVE_POWER -> generator.getMinP(); - case ACTIVE_POWER_SET_POINT -> generator.getTargetP(); - case RATED_NOMINAL_POWER -> generator.getRatedS(); - case REACTIVE_POWER_SET_POINT -> generator.getTargetQ(); - case VOLTAGE_SET_POINT -> generator.getTargetV(); - case PLANNED_ACTIVE_POWER_SET_POINT -> generatorStartup != null ? generatorStartup.getPlannedActivePowerSetpoint() : null; - case MARGINAL_COST -> generatorStartup != null ? generatorStartup.getMarginalCost() : null; - case PLANNED_OUTAGE_RATE -> generatorStartup != null ? generatorStartup.getPlannedOutageRate() : null; - case FORCED_OUTAGE_RATE -> generatorStartup != null ? generatorStartup.getForcedOutageRate() : null; - case DROOP -> activePowerControl != null ? activePowerControl.getDroop() : null; - case TRANSIENT_REACTANCE -> generatorShortCircuit != null ? generatorShortCircuit.getDirectTransX() : null; - case STEP_UP_TRANSFORMER_REACTANCE -> generatorShortCircuit != null ? generatorShortCircuit.getStepUpTransformerX() : null; - case Q_PERCENT -> coordinatedReactiveControl != null ? coordinatedReactiveControl.getQPercent() : null; - }; - } - - public static void setNewValue(Generator generator, String generatorField, double newValue) { - if (!Double.isNaN(newValue)) { - GeneratorField field = GeneratorField.valueOf(generatorField); - final AttributeModification attributeModification = new AttributeModification<>(newValue, OperationType.SET); - switch (field) { - case MAXIMUM_ACTIVE_POWER -> modifyGeneratorActiveLimitsAttributes( - attributeModification, null, null, generator, null); - case MINIMUM_ACTIVE_POWER -> modifyGeneratorActiveLimitsAttributes(null, attributeModification, null, generator, null); - case ACTIVE_POWER_SET_POINT -> { - ModificationUtils.getInstance().checkActivePowerZeroOrBetweenMinAndMaxActivePower( - attributeModification, null, null, - generator.getMinP(), generator.getMaxP(), generator.getTargetP(), - MODIFY_GENERATOR_ERROR, "Generator '" + generator.getId() + "' : " - ); - generator.setTargetP(newValue); - } - case RATED_NOMINAL_POWER -> modifyGeneratorActiveLimitsAttributes(null, null, attributeModification, generator, null); - case REACTIVE_POWER_SET_POINT -> modifyTargetQ(generator, attributeModification); - case VOLTAGE_SET_POINT -> modifyTargetV(generator, attributeModification); - case PLANNED_ACTIVE_POWER_SET_POINT -> - modifyGeneratorStartUpAttributes(attributeModification, null, null, null, generator, null, null); - case MARGINAL_COST -> - modifyGeneratorStartUpAttributes(null, attributeModification, null, null, generator, null, null); - case PLANNED_OUTAGE_RATE -> - modifyGeneratorStartUpAttributes(null, null, attributeModification, null, generator, null, null); - case FORCED_OUTAGE_RATE -> - modifyGeneratorStartUpAttributes(null, null, null, attributeModification, generator, null, null); - case DROOP -> { - ActivePowerControl activePowerControl = generator.getExtension(ActivePowerControl.class); - ActivePowerControlAdder activePowerControlAdder = generator.newExtension(ActivePowerControlAdder.class); - ModificationUtils.getInstance().modifyActivePowerControlAttributes(activePowerControl, activePowerControlAdder, null, - new AttributeModification<>((float) newValue, OperationType.SET), null, null); - } - case TRANSIENT_REACTANCE -> modifyGeneratorShortCircuitAttributes(attributeModification, null, generator, null); - case STEP_UP_TRANSFORMER_REACTANCE -> modifyGeneratorShortCircuitAttributes(null, attributeModification, generator, null); - case Q_PERCENT -> generator.newExtension(CoordinatedReactiveControlAdderImpl.class) - .withQPercent(newValue) - .add(); - } - } - } -} diff --git a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/AbstractAssignmentEntity.java b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/AbstractAssignmentEntity.java new file mode 100644 index 000000000..908298762 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/AbstractAssignmentEntity.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.entities.equipment.modification.byfilter; + +import jakarta.persistence.*; +import lombok.NoArgsConstructor; +import org.gridsuite.modification.server.dto.byfilter.AbstractAssignmentInfos; + +import java.util.UUID; + +/** + * @author Thang PHAM + */ +@NoArgsConstructor +@MappedSuperclass +public abstract class AbstractAssignmentEntity { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private UUID id; + + @Column + private String editedField; + + protected AbstractAssignmentEntity(AbstractAssignmentInfos abstractAssignmentInfos) { + this.id = null; + this.editedField = abstractAssignmentInfos.getEditedField(); + } + + protected void assignAttributes(AbstractAssignmentInfos modificationByFilterInfos) { + modificationByFilterInfos.setId(id); + modificationByFilterInfos.setEditedField(editedField); + } +} diff --git a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/ByFormulaModificationEntity.java b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/ByFormulaModificationEntity.java similarity index 92% rename from src/main/java/org/gridsuite/modification/server/entities/equipment/modification/ByFormulaModificationEntity.java rename to src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/ByFormulaModificationEntity.java index 384ff94d2..c925de273 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/ByFormulaModificationEntity.java +++ b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/ByFormulaModificationEntity.java @@ -1,15 +1,13 @@ -package org.gridsuite.modification.server.entities.equipment.modification; +package org.gridsuite.modification.server.entities.equipment.modification.byfilter; import com.powsybl.iidm.network.IdentifiableType; import jakarta.persistence.*; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.Setter; +import lombok.*; import org.gridsuite.modification.server.dto.ByFormulaModificationInfos; import org.gridsuite.modification.server.dto.ModificationInfos; -import org.gridsuite.modification.server.dto.formula.FormulaInfos; +import org.gridsuite.modification.server.dto.byfilter.formula.FormulaInfos; import org.gridsuite.modification.server.entities.ModificationEntity; +import org.gridsuite.modification.server.entities.equipment.modification.byfilter.formula.FormulaEntity; import java.util.List; import java.util.stream.Collectors; diff --git a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/ModificationByAssignmentEntity.java b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/ModificationByAssignmentEntity.java new file mode 100644 index 000000000..de90005f1 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/ModificationByAssignmentEntity.java @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.entities.equipment.modification.byfilter; + +import com.powsybl.iidm.network.IdentifiableType; +import jakarta.persistence.*; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.gridsuite.modification.server.dto.ModificationByAssignmentInfos; +import org.gridsuite.modification.server.dto.ModificationInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.AssignmentInfos; +import org.gridsuite.modification.server.entities.ModificationEntity; +import org.gridsuite.modification.server.entities.equipment.modification.byfilter.assignment.AssignmentEntity; + +import java.util.List; + +/** + * @author Thang PHAM + */ +@NoArgsConstructor +@Entity +@Table(name = "modificationByAssignment") +@PrimaryKeyJoinColumn(foreignKey = @ForeignKey(name = "modificationByAssignment_id_fk_constraint")) +public class ModificationByAssignmentEntity extends ModificationEntity { + @Enumerated(EnumType.STRING) + @Column + private IdentifiableType equipmentType; + + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + @JoinColumn(name = "modification_by_assignment_id", + foreignKey = @ForeignKey(name = "modification_by_assignment_id_fk")) + private List assignmentEntities; + + public ModificationByAssignmentEntity(ModificationByAssignmentInfos modificationByAssignmentInfos) { + super(modificationByAssignmentInfos); + assignAttributes(modificationByAssignmentInfos); + } + + @Override + public void update(@NonNull ModificationInfos modificationInfos) { + super.update(modificationInfos); + assignAttributes((ModificationByAssignmentInfos) modificationInfos); + } + + private void assignAttributes(ModificationByAssignmentInfos modificationByAssignmentInfos) { + this.equipmentType = modificationByAssignmentInfos.getEquipmentType(); + if (assignmentEntities == null) { + assignmentEntities = modificationByAssignmentInfos.getAssignmentInfosList() + .stream() + .map(AssignmentInfos::toEntity) + .toList(); + } else { + assignmentEntities.clear(); + assignmentEntities.addAll(modificationByAssignmentInfos.getAssignmentInfosList() + .stream() + .map(AssignmentInfos::toEntity) + .toList()); + } + } + + @Override + public ModificationByAssignmentInfos toModificationInfos() { + return toModificationByAssignmentInfosBuilder().build(); + } + + private ModificationByAssignmentInfos.ModificationByAssignmentInfosBuilder toModificationByAssignmentInfosBuilder() { + return ModificationByAssignmentInfos.builder() + .uuid(getId()) + .date(getDate()) + .stashed(getStashed()) + .activated(getActivated()) + .equipmentType(equipmentType) + .assignmentInfosList(assignmentEntities.stream() + .map(AssignmentEntity::toAssignmentInfos) + .toList() + ); + } +} diff --git a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/assignment/AssignmentEntity.java b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/assignment/AssignmentEntity.java new file mode 100644 index 000000000..ae1f2ee8c --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/assignment/AssignmentEntity.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.entities.equipment.modification.byfilter.assignment; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.gridsuite.modification.server.dto.FilterInfos; +import org.gridsuite.modification.server.dto.byfilter.DataType; +import org.gridsuite.modification.server.dto.byfilter.assignment.*; +import org.gridsuite.modification.server.entities.equipment.modification.VariationFilterEntity; +import org.gridsuite.modification.server.entities.equipment.modification.byfilter.AbstractAssignmentEntity; + +import java.util.List; + +/** + * @author Thang PHAM + */ +@NoArgsConstructor +@Entity +@Table(name = "assignment", indexes = @Index(name = "modification_by_assignment_id_idx", columnList = "modification_by_assignment_id")) +public class AssignmentEntity extends AbstractAssignmentEntity { + @Column + @Enumerated(EnumType.STRING) + private DataType dataType; + + @NotNull + @Column(name = "value_") // "value" is not supported in UT with H2 + private String value; // all values of different data types will be serialized as a string, deserialization is based on dataType + + @Setter + @Column + private String propertyName; // dedicated to an exceptional case, i.e. modify a property + + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + @JoinColumn(name = "assignment_id", + foreignKey = @ForeignKey(name = "assignment_id_fk")) + private List filters; + + public AssignmentEntity(AssignmentInfos assignmentInfos) { + super(assignmentInfos); + this.dataType = assignmentInfos.getDataType(); + this.value = assignmentInfos.getValue().toString(); + this.filters = assignmentInfos.getFilters().stream().map(FilterInfos::toEntity).toList(); + } + + public AssignmentInfos toAssignmentInfos() { + AssignmentInfos assignmentInfos = switch (dataType) { + case BOOLEAN -> BooleanAssignmentInfos.builder() + .value(Boolean.valueOf(value)) + .build(); + case INTEGER -> IntegerAssignmentInfos.builder() + .value(Integer.valueOf(value)) + .build(); + case DOUBLE -> DoubleAssignmentInfos.builder() + .value(Double.valueOf(value)) + .build(); + case ENUM -> EnumAssignmentInfos.builder() + .value(value) + .build(); + case PROPERTY -> PropertyAssignmentInfos.builder() + .value(value) + .propertyName(propertyName) + .build(); + }; + + assignAttributes(assignmentInfos); + assignmentInfos.setFilters(filters.stream() + .map(filterEntity -> new FilterInfos(filterEntity.getFilterId(), filterEntity.getName())) + .toList()); + return assignmentInfos; + } +} diff --git a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/FormulaEntity.java b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/formula/FormulaEntity.java similarity index 64% rename from src/main/java/org/gridsuite/modification/server/entities/equipment/modification/FormulaEntity.java rename to src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/formula/FormulaEntity.java index 1ea147165..4c2b4cdd0 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/FormulaEntity.java +++ b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/byfilter/formula/FormulaEntity.java @@ -5,44 +5,32 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.entities.equipment.modification; +package org.gridsuite.modification.server.entities.equipment.modification.byfilter.formula; import jakarta.persistence.*; -import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; import org.gridsuite.modification.server.dto.FilterInfos; -import org.gridsuite.modification.server.dto.formula.FormulaInfos; -import org.gridsuite.modification.server.dto.formula.Operator; -import org.gridsuite.modification.server.dto.formula.ReferenceFieldOrValue; +import org.gridsuite.modification.server.dto.byfilter.formula.FormulaInfos; +import org.gridsuite.modification.server.dto.byfilter.formula.Operator; +import org.gridsuite.modification.server.dto.byfilter.formula.ReferenceFieldOrValue; +import org.gridsuite.modification.server.entities.equipment.modification.VariationFilterEntity; +import org.gridsuite.modification.server.entities.equipment.modification.byfilter.AbstractAssignmentEntity; import java.util.List; -import java.util.UUID; -import java.util.stream.Collectors; /** * @author Seddik Yengui */ @NoArgsConstructor -@Getter -@Setter @Entity @Table(name = "formula", indexes = @Index(name = "by_formula_modification_id_idx", columnList = "by_formula_modification_id")) -public class FormulaEntity { - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - @Column(name = "id") - private UUID id; - +public class FormulaEntity extends AbstractAssignmentEntity { @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) @JoinColumn(name = "formula_id", foreignKey = @ForeignKey(name = "formula_id_fk")) private List filters; - @Column - private String editedField; - @Column private String equipmentField1; @@ -59,32 +47,31 @@ public class FormulaEntity { private Operator operator; public FormulaEntity(FormulaInfos formulaInfos) { - this.id = null; - this.filters = formulaInfos.getFilters().stream().map(FilterInfos::toEntity).collect(Collectors.toList()); - this.editedField = formulaInfos.getEditedField(); + super(formulaInfos); this.equipmentField1 = formulaInfos.getFieldOrValue1().getEquipmentField(); this.equipmentField2 = formulaInfos.getFieldOrValue2().getEquipmentField(); this.value1 = formulaInfos.getFieldOrValue1().getValue(); this.value2 = formulaInfos.getFieldOrValue2().getValue(); this.operator = formulaInfos.getOperator(); + this.filters = formulaInfos.getFilters().stream().map(FilterInfos::toEntity).toList(); } public FormulaInfos toFormulaInfos() { - return FormulaInfos.builder() - .id(getId()) - .filters(getFilters().stream() + FormulaInfos formulaInfos = FormulaInfos.builder() + .filters(filters.stream() .map(filterEntity -> new FilterInfos(filterEntity.getFilterId(), filterEntity.getName())) - .collect(Collectors.toList())) - .editedField(getEditedField()) + .toList()) .fieldOrValue1(ReferenceFieldOrValue.builder() - .equipmentField(getEquipmentField1()) - .value(getValue1()) + .equipmentField(equipmentField1) + .value(value1) .build()) .fieldOrValue2(ReferenceFieldOrValue.builder() - .equipmentField(getEquipmentField2()) - .value(getValue2()) + .equipmentField(equipmentField2) + .value(value2) .build()) - .operator(getOperator()) + .operator(operator) .build(); + assignAttributes(formulaInfos); + return formulaInfos; } } diff --git a/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java b/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java deleted file mode 100644 index a1f119008..000000000 --- a/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java +++ /dev/null @@ -1,307 +0,0 @@ -/** - * Copyright (c) 2023, 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/. - */ - -package org.gridsuite.modification.server.modifications; - -import com.powsybl.commons.report.ReportNode; -import com.powsybl.commons.report.TypedValue; -import com.powsybl.iidm.network.*; -import org.gridsuite.modification.server.NetworkModificationException; -import org.gridsuite.modification.server.dto.ByFormulaModificationInfos; -import org.gridsuite.modification.server.dto.FilterEquipments; -import org.gridsuite.modification.server.dto.FilterInfos; -import org.gridsuite.modification.server.dto.formula.FormulaInfos; -import org.gridsuite.modification.server.dto.formula.Operator; -import org.gridsuite.modification.server.dto.formula.equipmentfield.*; -import org.gridsuite.modification.server.service.FilterService; -import org.jetbrains.annotations.NotNull; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.stream.Collectors; - -import static org.gridsuite.modification.server.modifications.ModificationUtils.*; - -public class ByFormulaModification extends AbstractModification { - public static final String EQUIPMENT_MODIFIED_REPORT_ERROR = "EquipmentModifiedReportError_"; - public static final String KEY_FILTER_NAME = "filterName"; - public static final String KEY_FIELD_NAME = "fieldName"; - public static final String KEY_EQPT_NAME = "eqptName"; - public static final String KEY_EQPT_TYPE = "eqptType"; - public static final String KEY_NB_CHANGED = "nbChanged"; - public static final String KEY_NB_UNCHANGED = "nbUnchanged"; - public static final String KEY_VALUE = "value"; - private final ByFormulaModificationInfos modificationInfos; - protected FilterService filterService; - private int equipmentNotModifiedCount; - private long equipmentCount; - private long equipmentNotFoundCount; - - public ByFormulaModification(ByFormulaModificationInfos modificationInfos) { - this.modificationInfos = modificationInfos; - equipmentNotModifiedCount = 0; - equipmentCount = 0; - equipmentNotFoundCount = 0; - } - - @Override - public void initApplicationContext(NetworkModificationApplicator modificationApplicator) { - filterService = modificationApplicator.getFilterService(); - } - - @Override - public void check(Network network) throws NetworkModificationException { - if (modificationInfos == null) { - throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, "Missing required attributes to modify the equipment"); - } - - if (CollectionUtils.isEmpty(modificationInfos.getFormulaInfosList())) { - throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, "At least one formula is required"); - } - - if (modificationInfos.getFormulaInfosList().stream().anyMatch(formulaInfos -> CollectionUtils.isEmpty(formulaInfos.getFilters()))) { - throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, "Every formula must have at least one filter"); - } - } - - @Override - public void apply(Network network, ReportNode subReportNode) { - // collect all filters from all variations - Map filters = modificationInfos.getFormulaInfosList().stream() - .flatMap(v -> v.getFilters().stream()) - .filter(distinctByKey(FilterInfos::getId)) - .collect(Collectors.toMap(FilterInfos::getId, FilterInfos::getName)); - - Map exportFilters = ModificationUtils.getUuidFilterEquipmentsMap(filterService, network, subReportNode, filters, modificationInfos.getErrorType()); - - if (exportFilters != null) { - ReportNode formulaSubReporter = subReportNode.newReportNode().withMessageTemplate("appliedFormulasModifications", "Formulas").add(); - List formulaReports = new ArrayList<>(); - modificationInfos.getFormulaInfosList().forEach(formulaInfos -> - formulaInfos.getFilters().forEach(filterInfos -> - applyFormulaOnFilterEquipments(network, exportFilters, formulaReports, formulaInfos, filterInfos))); - subReportNode.newReportNode() - .withMessageTemplate("byFormulaModification", "New modification by formula on ${" + KEY_EQPT_TYPE + "}") - .withUntypedValue(KEY_EQPT_TYPE, modificationInfos.getIdentifiableType().name()) - .withSeverity(TypedValue.INFO_SEVERITY) - .add(); - if (equipmentNotModifiedCount == 0 && equipmentNotFoundCount == 0) { - subReportNode.newReportNode() - .withMessageTemplate("byFormulaModificationALL", "All equipment have been modified : ${" + KEY_VALUE + "} equipment(s)") - .withUntypedValue(KEY_VALUE, equipmentCount) - .withSeverity(TypedValue.INFO_SEVERITY) - .add(); - } else { - if (equipmentNotModifiedCount == equipmentCount) { - createReport(subReportNode, "byFormulaModificationNone", - "No equipment have been modified", - Map.of(), TypedValue.ERROR_SEVERITY); - } else { - subReportNode.newReportNode() - .withMessageTemplate("byFormulaModificationSome", "Some of the equipment have been modified : ${" + KEY_NB_CHANGED + "} equipment(s) modified and ${" + KEY_NB_UNCHANGED + "} equipment(s) not modified") - .withUntypedValue(KEY_NB_CHANGED, equipmentCount - equipmentNotModifiedCount) - .withUntypedValue(KEY_NB_UNCHANGED, equipmentNotModifiedCount + equipmentNotFoundCount) - .withSeverity(TypedValue.WARN_SEVERITY) - .add(); - } - } - report(formulaSubReporter, formulaReports); - } - } - - private void report(ReportNode formulaSubReportNode, List formulaReports) { - formulaReports.forEach(report -> insertReportNode(formulaSubReportNode, report)); - } - - private void applyFormulaOnFilterEquipments(Network network, - Map exportFilters, - List formulaReports, - FormulaInfos formulaInfos, - FilterInfos filterInfos) { - FilterEquipments filterEquipments = exportFilters.get(filterInfos.getId()); - - if (CollectionUtils.isEmpty(filterEquipments.getIdentifiableAttributes())) { - formulaReports.add(ReportNode.newRootReportNode() - .withMessageTemplate("byFormulaModificationFormulaFilter_" + formulaReports.size(), "No equipments were found for filter ${" + KEY_FILTER_NAME + "}") - .withUntypedValue(KEY_FILTER_NAME, filterInfos.getName()) - .withSeverity(TypedValue.WARN_SEVERITY) - .build()); - } else { - equipmentCount += filterEquipments.getIdentifiableAttributes().size(); - if (!CollectionUtils.isEmpty(filterEquipments.getNotFoundEquipments())) { - equipmentNotFoundCount += filterEquipments.getNotFoundEquipments().size(); - } - List notEditableEquipments = new ArrayList<>(); - List equipmentsReport = new ArrayList<>(); - filterEquipments.getIdentifiableAttributes() - .stream() - .map(attributes -> network.getIdentifiable(attributes.getId())) - .filter(identifiable -> { - boolean isEditableEquipment = isEquipmentEditable(identifiable, formulaInfos, equipmentsReport); - if (!isEditableEquipment) { - notEditableEquipments.add(identifiable.getId()); - equipmentNotModifiedCount += 1; - } - return isEditableEquipment; - }) - .forEach(identifiable -> applyFormula(identifiable, formulaInfos, equipmentsReport, notEditableEquipments)); - - createFormulaReports(formulaReports, formulaInfos, filterInfos, filterEquipments, notEditableEquipments); - - formulaReports.addAll(equipmentsReport); - } - } - - private void createFormulaReports(List formulaReports, FormulaInfos formulaInfos, FilterInfos filterInfos, FilterEquipments filterEquipments, List notEditableEquipments) { - if (notEditableEquipments.size() == filterEquipments.getIdentifiableAttributes().size()) { - formulaReports.add(ReportNode.newRootReportNode() - .withMessageTemplate("byFormulaModificationFormulaFilterFailed_" + formulaReports.size(), "No equipment(s) have been modified on filter ${" + KEY_FILTER_NAME + "}") - .withUntypedValue(KEY_FILTER_NAME, filterInfos.getName()) - .withSeverity(TypedValue.WARN_SEVERITY) - .build()); - } else { - formulaReports.add(ReportNode.newRootReportNode() - .withMessageTemplate("byFormulaModificationFormulaFilter_" + formulaReports.size(), "Successful application of new modification by formula on filter ${" + KEY_FILTER_NAME + "}") - .withUntypedValue(KEY_FILTER_NAME, filterInfos.getName()) - .withSeverity(TypedValue.INFO_SEVERITY) - .build()); - - formulaReports.add(ReportNode.newRootReportNode() - .withMessageTemplate("numberOfValidEquipment" + formulaReports.size(), " Number of equipment modified : ${" + KEY_NB_CHANGED + "}") - .withUntypedValue(KEY_NB_CHANGED, filterEquipments.getIdentifiableAttributes().size() - notEditableEquipments.size()) - .withSeverity(TypedValue.INFO_SEVERITY) - .build()); - - if (!CollectionUtils.isEmpty(notEditableEquipments)) { - formulaReports.add(ReportNode.newRootReportNode() - .withMessageTemplate("NotEditedEquipmentsFilter_" + formulaReports.size(), " ${" + KEY_NB_UNCHANGED + "} equipment(s) were not modified") - .withUntypedValue(KEY_NB_UNCHANGED, notEditableEquipments.size()) - .withSeverity(TypedValue.WARN_SEVERITY) - .build()); - } - } - - formulaReports.add(ReportNode.newRootReportNode() - .withMessageTemplate("editedFieldFilter_" + formulaReports.size(), " Edited field :${" + KEY_FIELD_NAME + "}") - .withUntypedValue(KEY_FIELD_NAME, formulaInfos.getEditedField()) - .withSeverity(TypedValue.INFO_SEVERITY) - .build()); - - if (!CollectionUtils.isEmpty(filterEquipments.getNotFoundEquipments())) { - String equipmentIds = String.join(", ", filterEquipments.getNotFoundEquipments()); - formulaReports.add(ReportNode.newRootReportNode() - .withMessageTemplate("filterEquipmentsNotFound_" + formulaReports.size(), " Equipment not found : ${" + KEY_VALUE + "}") - .withUntypedValue(KEY_VALUE, equipmentIds) - .withSeverity(TypedValue.WARN_SEVERITY) - .build()); - } - } - - private boolean isEquipmentEditable(Identifiable identifiable, - FormulaInfos formulaInfos, - List equipmentsReport) { - if (formulaInfos.getEditedField() == null) { - return false; - } - - if (identifiable.getType() == IdentifiableType.TWO_WINDINGS_TRANSFORMER) { - TwoWindingsTransformerField editedField = TwoWindingsTransformerField.valueOf(formulaInfos.getEditedField()); - TwoWindingsTransformer twoWindingsTransformer = (TwoWindingsTransformer) identifiable; - return switch (editedField) { - case TARGET_V, RATIO_LOW_TAP_POSITION, RATIO_TAP_POSITION, RATIO_TARGET_DEADBAND -> { - boolean isEditable = twoWindingsTransformer.getRatioTapChanger() != null; - if (!isEditable) { - equipmentsReport.add(ReportNode.newRootReportNode() - .withMessageTemplate(EQUIPMENT_MODIFIED_REPORT_ERROR + equipmentsReport.size(), " Cannot modify field ${" + KEY_FIELD_NAME + "} of equipment ${" + KEY_EQPT_NAME + "} : Ratio tab changer is null") - .withUntypedValue(KEY_FIELD_NAME, editedField.name()) - .withUntypedValue(KEY_EQPT_NAME, identifiable.getId()) - .withSeverity(TypedValue.TRACE_SEVERITY) - .build()); - } - yield isEditable; - } - case REGULATION_VALUE, PHASE_LOW_TAP_POSITION, PHASE_TAP_POSITION, PHASE_TARGET_DEADBAND -> { - boolean isEditable = twoWindingsTransformer.getPhaseTapChanger() != null; - if (!isEditable) { - equipmentsReport.add(ReportNode.newRootReportNode() - .withMessageTemplate(EQUIPMENT_MODIFIED_REPORT_ERROR + equipmentsReport.size(), " Cannot modify field ${" + KEY_FIELD_NAME + "} of equipment ${" + KEY_EQPT_NAME + "} : Phase tab changer is null") - .withUntypedValue(KEY_FIELD_NAME, editedField.name()) - .withUntypedValue(KEY_EQPT_NAME, identifiable.getId()) - .withSeverity(TypedValue.TRACE_SEVERITY) - .build()); - } - yield isEditable; - } - default -> true; - }; - } - return true; - } - - private void applyFormula(Identifiable identifiable, - FormulaInfos formulaInfos, - List reports, - List notEditableEquipments) { - Double value1 = formulaInfos.getFieldOrValue1().getRefOrValue(identifiable); - Double value2 = formulaInfos.getFieldOrValue2().getRefOrValue(identifiable); - if (value1 == null || Double.isNaN(value1) || value2 == null || Double.isNaN(value2)) { - equipmentNotModifiedCount += 1; - notEditableEquipments.add(identifiable.getId()); - reports.add(ReportNode.newRootReportNode() - .withMessageTemplate(EQUIPMENT_MODIFIED_REPORT_ERROR + reports.size(), " Cannot modify equipment ${" + KEY_EQPT_NAME + "} : At least one of the value or referenced field is null") - .withUntypedValue(KEY_EQPT_NAME, identifiable.getId()) - .withSeverity(TypedValue.TRACE_SEVERITY) - .build()); - } else if (value2 == 0 && formulaInfos.getOperator() == Operator.DIVISION) { - equipmentNotModifiedCount += 1; - notEditableEquipments.add(identifiable.getId()); - } else { - try { - final Double newValue = applyOperation(formulaInfos.getOperator(), value1, value2); - switch (identifiable.getType()) { - case GENERATOR -> GeneratorField.setNewValue((Generator) identifiable, formulaInfos.getEditedField(), newValue.doubleValue()); - case BATTERY -> BatteryField.setNewValue((Battery) identifiable, formulaInfos.getEditedField(), newValue); - case SHUNT_COMPENSATOR -> ShuntCompensatorField.setNewValue((ShuntCompensator) identifiable, formulaInfos.getEditedField(), newValue); - case VOLTAGE_LEVEL -> VoltageLevelField.setNewValue((VoltageLevel) identifiable, formulaInfos.getEditedField(), newValue); - case LOAD -> LoadField.setNewValue((Load) identifiable, formulaInfos.getEditedField(), newValue); - case TWO_WINDINGS_TRANSFORMER -> TwoWindingsTransformerField.setNewValue((TwoWindingsTransformer) identifiable, formulaInfos.getEditedField(), newValue); - default -> throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, "Unsupported equipment"); - } - reports.add(ReportNode.newRootReportNode() - .withMessageTemplate("EquipmentModifiedReport_" + reports.size(), " ${" + KEY_EQPT_TYPE + "} id : ${" + KEY_EQPT_NAME + "}, new value of ${" + KEY_FIELD_NAME + "} : ${" + KEY_VALUE + "}") - .withUntypedValue(KEY_EQPT_TYPE, modificationInfos.getIdentifiableType().name()) - .withUntypedValue(KEY_EQPT_NAME, identifiable.getId()) - .withUntypedValue(KEY_FIELD_NAME, formulaInfos.getEditedField()) - .withUntypedValue(KEY_VALUE, newValue) - .withSeverity(TypedValue.TRACE_SEVERITY) - .build()); - } catch (Exception e) { - notEditableEquipments.add(identifiable.getId()); - equipmentNotModifiedCount += 1; - reports.add(ReportNode.newRootReportNode() - .withMessageTemplate("EquipmentModifiedReportExceptionf_" + reports.size(), " Cannot modify equipment ${" + KEY_EQPT_NAME + "} : ${" + KEY_VALUE + "}") - .withUntypedValue(KEY_EQPT_NAME, identifiable.getId()) - .withUntypedValue(KEY_VALUE, e.getMessage()) - .withSeverity(TypedValue.TRACE_SEVERITY) - .build()); - } - } - } - - private Double applyOperation(Operator operator, @NotNull Double value1, @NotNull Double value2) { - return switch (operator) { - case ADDITION -> value1 + value2; - case SUBTRACTION -> value1 - value2; - case MULTIPLICATION -> value1 * value2; - case DIVISION -> value1 / value2; - case PERCENTAGE -> value1 * (value2 / 100); - }; - } -} diff --git a/src/main/java/org/gridsuite/modification/server/modifications/byfilter/AbstractModificationByAssignment.java b/src/main/java/org/gridsuite/modification/server/modifications/byfilter/AbstractModificationByAssignment.java new file mode 100644 index 000000000..33fe17929 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/modifications/byfilter/AbstractModificationByAssignment.java @@ -0,0 +1,368 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.modifications.byfilter; + +import com.powsybl.commons.report.ReportNode; +import com.powsybl.commons.report.TypedValue; +import com.powsybl.iidm.network.Identifiable; +import com.powsybl.iidm.network.IdentifiableType; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.TwoWindingsTransformer; +import org.apache.commons.lang3.StringUtils; +import org.gridsuite.modification.server.NetworkModificationException; +import org.gridsuite.modification.server.dto.FilterEquipments; +import org.gridsuite.modification.server.dto.FilterInfos; +import org.gridsuite.modification.server.dto.ModificationInfos; +import org.gridsuite.modification.server.dto.byfilter.AbstractAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.TwoWindingsTransformerField; +import org.gridsuite.modification.server.modifications.AbstractModification; +import org.gridsuite.modification.server.modifications.ModificationUtils; +import org.gridsuite.modification.server.modifications.NetworkModificationApplicator; +import org.gridsuite.modification.server.service.FilterService; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + +import static org.gridsuite.modification.server.dto.byfilter.equipmentfield.FieldUtils.getFieldValue; +import static org.gridsuite.modification.server.dto.byfilter.equipmentfield.FieldUtils.setFieldValue; +import static org.gridsuite.modification.server.modifications.ModificationUtils.*; + +/** + * @author Thang PHAM + */ +public abstract class AbstractModificationByAssignment extends AbstractModification { + public static final String VALUE_KEY_FILTER_NAME = "filterName"; + public static final String VALUE_KEY_FIELD_NAME = "fieldName"; + public static final String VALUE_KEY_EQUIPMENT_NAME = "equipmentName"; + public static final String VALUE_KEY_EQUIPMENT_TYPE = "equipmentType"; + public static final String VALUE_KEY_EQUIPMENT_COUNT = "equipmentCount"; + public static final String VALUE_KEY_EQUIPMENT_IDS = "equipmentIds"; + public static final String VALUE_KEY_NB_CHANGED = "nbChanged"; + public static final String VALUE_KEY_NB_UNCHANGED = "nbUnchanged"; + public static final String VALUE_KEY_OLD_VALUE = "oldValue"; + public static final String VALUE_KEY_NEW_VALUE = "newValue"; + public static final String VALUE_KEY_MODIFICATION_TYPE_LABEL = "modificationTypeLabel"; + public static final String VALUE_KEY_FILTERS_EACH_ASSIGNMENT = "filtersEachAssignment"; + public static final String VALUE_KEY_ERROR_MESSAGE = "errorMessage"; + public static final String REPORT_KEY_RATIO_TAP_CHANGER_EQUIPMENT_MODIFIED_ERROR = "ratioTapChangerEquipmentModifiedError"; + public static final String REPORT_KEY_PHASE_TAP_CHANGER_EQUIPMENT_MODIFIED_ERROR = "phaseTapChangerEquipmentModifiedError"; + public static final String REPORT_KEY_EQUIPMENT_MODIFIED_ERROR = "equipmentModifiedError"; + public static final String REPORT_KEY_BY_FILTER_MODIFICATION_SOME = "byFilterModificationSome"; + public static final String REPORT_KEY_BY_FILTER_MODIFICATION_FAILED = "byFilterModificationFailed"; + public static final String REPORT_KEY_BY_FILTER_MODIFICATION_SUCCESS = "byFilterModificationSuccess"; + public static final String REPORT_KEY_NUMBER_OF_VALID_EQUIPMENT = "numberOfValidEquipment"; + public static final String REPORT_KEY_NOT_EDITED_EQUIPMENTS_FILTER = "notEditedEquipmentsFilter"; + public static final String REPORT_KEY_EDITED_FIELD_FILTER = "editedFieldFilter"; + public static final String REPORT_KEY_FILTER_EQUIPMENTS_NOT_FOUND = "filterEquipmentsNotFound"; + public static final String REPORT_KEY_EQUIPMENT_MODIFIED_REPORT = "equipmentModifiedReport"; + public static final String REPORT_KEY_EQUIPMENT_MODIFIED_REPORT_EXCEPTION = "equipmentModifiedReportException"; + public static final String REPORT_KEY_APPLIED_BY_FILTER_MODIFICATIONS = "appliedByFilterModifications"; + public static final String REPORT_KEY_APPLIED_ASSIGNMENT = "appliedAssignment"; + public static final String REPORT_KEY_BY_FILTER_MODIFICATION_ALL = "byFilterModificationAll"; + public static final String REPORT_KEY_BY_FILTER_MODIFICATION_NONE = "byFilterModificationNone"; + public static final String REPORT_KEY_BY_FILTER_MODIFICATION_NOT_FOUND = "byFilterModificationNotFound"; + + protected FilterService filterService; + protected int equipmentNotModifiedCount; + protected long equipmentCount; + protected long equipmentNotFoundCount; + + protected AbstractModificationByAssignment() { + equipmentNotModifiedCount = 0; + equipmentCount = 0; + equipmentNotFoundCount = 0; + } + + public abstract String getModificationTypeLabel(); + + private String getEditedFieldLabel(AbstractAssignmentInfos modificationByFilterInfos) { + return modificationByFilterInfos.getEditedFieldLabel(); + } + + public abstract ModificationInfos getModificationInfos(); + + public abstract IdentifiableType getEquipmentType(); + + public abstract NetworkModificationException.Type getExceptionType(); + + public abstract List getAssignmentInfosList(); + + protected abstract boolean preCheckValue(Identifiable equipment, + AbstractAssignmentInfos abstractAssignmentInfos, + List reports, List notEditableEquipments); + + protected abstract String getNewValue(Identifiable equipment, AbstractAssignmentInfos abstractAssignmentInfos); + + protected String getOldValue(Identifiable equipment, AbstractAssignmentInfos abstractAssignmentInfos) { + return getFieldValue(equipment, abstractAssignmentInfos.getEditedField()); + } + + protected String applyValue(Identifiable equipment, AbstractAssignmentInfos abstractAssignmentInfos) { + // get new value + String newValue = getNewValue(equipment, abstractAssignmentInfos); + + // set new value for the equipment + setFieldValue(equipment, abstractAssignmentInfos.getEditedField(), newValue); + return newValue; + } + + @Override + public void initApplicationContext(NetworkModificationApplicator modificationApplicator) { + filterService = modificationApplicator.getFilterService(); + } + + @Override + public void check(Network network) throws NetworkModificationException { + if (getModificationInfos() == null) { + throw new NetworkModificationException(getExceptionType(), "Missing required attributes to modify the equipment"); + } + + if (CollectionUtils.isEmpty(getAssignmentInfosList())) { + throw new NetworkModificationException(getExceptionType(), String.format("At least one %s is required", getModificationTypeLabel())); + } + + if (getAssignmentInfosList().stream().anyMatch(modificationByFilterInfos -> CollectionUtils.isEmpty(modificationByFilterInfos.getFilters()))) { + throw new NetworkModificationException(getExceptionType(), String.format("Every %s must have at least one filter", getModificationTypeLabel())); + } + } + + @Override + public void apply(Network network, ReportNode subReportNode) { + // collect all filters from all variations + Map filters = getFilters(); + + Map filterUuidEquipmentsMap = + ModificationUtils.getUuidFilterEquipmentsMap(filterService, network, subReportNode, filters, getModificationInfos().getErrorType()); + + if (filterUuidEquipmentsMap != null) { + ReportNode subReporter = subReportNode.newReportNode() + .withMessageTemplate(REPORT_KEY_APPLIED_BY_FILTER_MODIFICATIONS, "${" + VALUE_KEY_MODIFICATION_TYPE_LABEL + "}s on ${" + VALUE_KEY_EQUIPMENT_TYPE + "} type") + .withUntypedValue(VALUE_KEY_MODIFICATION_TYPE_LABEL, StringUtils.capitalize(getModificationTypeLabel())) + .withUntypedValue(VALUE_KEY_EQUIPMENT_TYPE, getEquipmentType().name()) + .add(); + // perform modifications + getAssignmentInfosList().forEach(abstractAssignmentInfos -> { + List reports = new ArrayList<>(); + ReportNode eachAssignmentReporter = subReporter.newReportNode() + .withMessageTemplate(REPORT_KEY_APPLIED_ASSIGNMENT, "${" + VALUE_KEY_MODIFICATION_TYPE_LABEL + "} on filters : ${" + VALUE_KEY_FILTERS_EACH_ASSIGNMENT + "}") + .withUntypedValue(VALUE_KEY_MODIFICATION_TYPE_LABEL, StringUtils.capitalize(getModificationTypeLabel())) + .withUntypedValue(VALUE_KEY_FILTERS_EACH_ASSIGNMENT, abstractAssignmentInfos.getFilters().stream().map(FilterInfos::getName) + .collect(Collectors.joining(", "))) + .add(); + abstractAssignmentInfos.getFilters().forEach(filterInfos -> applyOnFilterEquipments(network, filterUuidEquipmentsMap, reports, abstractAssignmentInfos, filterInfos)); + reports.forEach(report -> insertReportNode(eachAssignmentReporter, report)); + }); + // reporting + if (equipmentNotModifiedCount == 0 && equipmentNotFoundCount == 0) { + subReportNode.newReportNode() + .withMessageTemplate(REPORT_KEY_BY_FILTER_MODIFICATION_ALL, + "All equipments have been modified : ${" + VALUE_KEY_EQUIPMENT_COUNT + "} equipment(s)") + .withUntypedValue(VALUE_KEY_EQUIPMENT_COUNT, equipmentCount) + .withSeverity(TypedValue.INFO_SEVERITY) + .add(); + + } else { + if (equipmentNotModifiedCount == equipmentCount) { + createReport(subReportNode, REPORT_KEY_BY_FILTER_MODIFICATION_NONE, + "No equipment have been modified", + Map.of(), TypedValue.ERROR_SEVERITY); + } else { + subReportNode.newReportNode() + .withMessageTemplate(REPORT_KEY_BY_FILTER_MODIFICATION_SOME, + "Some of the equipment have been modified : ${" + VALUE_KEY_NB_CHANGED + "} equipment(s) modified and ${" + VALUE_KEY_NB_UNCHANGED + "} equipment(s) not modified") + .withUntypedValue(VALUE_KEY_NB_CHANGED, equipmentCount - equipmentNotModifiedCount) + .withUntypedValue(VALUE_KEY_NB_UNCHANGED, equipmentNotModifiedCount + equipmentNotFoundCount) + .withSeverity(TypedValue.WARN_SEVERITY) + .add(); + } + } + } + } + + protected boolean isEquipmentEditable(Identifiable equipment, + AbstractAssignmentInfos abstractAssignmentInfos, + List equipmentsReport) { + if (abstractAssignmentInfos.getEditedField() == null) { + return false; + } + + if (equipment.getType() == IdentifiableType.TWO_WINDINGS_TRANSFORMER) { + TwoWindingsTransformerField editedField = TwoWindingsTransformerField.valueOf(abstractAssignmentInfos.getEditedField()); + TwoWindingsTransformer twoWindingsTransformer = (TwoWindingsTransformer) equipment; + return switch (editedField) { + case TARGET_V, RATIO_LOW_TAP_POSITION, RATIO_TAP_POSITION, RATIO_TARGET_DEADBAND -> { + boolean isEditable = twoWindingsTransformer.getRatioTapChanger() != null; + if (!isEditable) { + equipmentsReport.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_RATIO_TAP_CHANGER_EQUIPMENT_MODIFIED_ERROR + equipmentsReport.size(), + " Cannot modify field ${" + VALUE_KEY_FIELD_NAME + "} of equipment ${" + VALUE_KEY_EQUIPMENT_NAME + "} : Ratio tab changer is null") + .withUntypedValue(VALUE_KEY_FIELD_NAME, editedField.name()) + .withUntypedValue(VALUE_KEY_EQUIPMENT_NAME, equipment.getId()) + .withSeverity(TypedValue.TRACE_SEVERITY) + .build()); + } + yield isEditable; + } + case REGULATION_VALUE, PHASE_LOW_TAP_POSITION, PHASE_TAP_POSITION, PHASE_TARGET_DEADBAND -> { + boolean isEditable = twoWindingsTransformer.getPhaseTapChanger() != null; + if (!isEditable) { + equipmentsReport.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_PHASE_TAP_CHANGER_EQUIPMENT_MODIFIED_ERROR + equipmentsReport.size(), + " Cannot modify field ${" + VALUE_KEY_FIELD_NAME + "} of equipment ${" + VALUE_KEY_EQUIPMENT_NAME + "} : Phase tab changer is null") + .withUntypedValue(VALUE_KEY_FIELD_NAME, editedField.name()) + .withUntypedValue(VALUE_KEY_EQUIPMENT_NAME, equipment.getId()) + .withSeverity(TypedValue.TRACE_SEVERITY) + .build()); + } + yield isEditable; + } + default -> true; + }; + } + return true; + } + + private void createAssignmentReports(List reports, AbstractAssignmentInfos abstractAssignmentInfos, + FilterInfos filterInfos, FilterEquipments filterEquipments, List notEditableEquipments) { + if (notEditableEquipments.size() == filterEquipments.getIdentifiableAttributes().size()) { + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_BY_FILTER_MODIFICATION_FAILED, + "No equipment(s) have been modified on filter ${" + VALUE_KEY_FILTER_NAME + "}") + .withUntypedValue(VALUE_KEY_FILTER_NAME, filterInfos.getName()) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } else { + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_BY_FILTER_MODIFICATION_SUCCESS, + "Successful application of ${" + VALUE_KEY_MODIFICATION_TYPE_LABEL + "} on filter ${" + VALUE_KEY_FILTER_NAME + "}") + .withUntypedValue(VALUE_KEY_MODIFICATION_TYPE_LABEL, getModificationTypeLabel()) + .withUntypedValue(VALUE_KEY_FILTER_NAME, filterInfos.getName()) + .withSeverity(TypedValue.INFO_SEVERITY) + .build()); + + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_NUMBER_OF_VALID_EQUIPMENT, " Number of equipment modified : ${" + VALUE_KEY_NB_CHANGED + "}") + .withUntypedValue(VALUE_KEY_NB_CHANGED, filterEquipments.getIdentifiableAttributes().size() - notEditableEquipments.size()) + .withSeverity(TypedValue.INFO_SEVERITY) + .build()); + + if (!CollectionUtils.isEmpty(notEditableEquipments)) { + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_NOT_EDITED_EQUIPMENTS_FILTER, + " ${" + VALUE_KEY_NB_UNCHANGED + "} equipment(s) were not modified") + .withUntypedValue(VALUE_KEY_NB_UNCHANGED, notEditableEquipments.size()) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } + } + + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_EDITED_FIELD_FILTER, " Edited field : ${" + VALUE_KEY_FIELD_NAME + "}") + .withUntypedValue(VALUE_KEY_FIELD_NAME, getEditedFieldLabel(abstractAssignmentInfos)) + .withSeverity(TypedValue.INFO_SEVERITY) + .build()); + + if (!CollectionUtils.isEmpty(filterEquipments.getNotFoundEquipments())) { + String equipmentIds = String.join(", ", filterEquipments.getNotFoundEquipments()); + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_FILTER_EQUIPMENTS_NOT_FOUND, " Equipment not found : ${" + VALUE_KEY_EQUIPMENT_IDS + "}") + .withUntypedValue(VALUE_KEY_EQUIPMENT_IDS, equipmentIds) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } + } + + private void applyModification(Identifiable equipment, + AbstractAssignmentInfos abstractAssignmentInfos, + List reports, + List notEditableEquipments) { + + // check pre-conditions + if (!preCheckValue(equipment, abstractAssignmentInfos, reports, notEditableEquipments)) { + return; + } + + // perform to apply new value + try { + final String oldValue = getOldValue(equipment, abstractAssignmentInfos); + final String newValue = applyValue(equipment, abstractAssignmentInfos); + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_EQUIPMENT_MODIFIED_REPORT, + " ${" + VALUE_KEY_EQUIPMENT_TYPE + "} id : ${" + VALUE_KEY_EQUIPMENT_NAME + + "}, ${" + VALUE_KEY_FIELD_NAME + "} : ${" + VALUE_KEY_OLD_VALUE + "} → ${" + VALUE_KEY_NEW_VALUE + "}") + .withUntypedValue(VALUE_KEY_EQUIPMENT_TYPE, equipment.getType().name()) + .withUntypedValue(VALUE_KEY_EQUIPMENT_NAME, equipment.getId()) + .withUntypedValue(VALUE_KEY_FIELD_NAME, getEditedFieldLabel(abstractAssignmentInfos)) + .withUntypedValue(VALUE_KEY_OLD_VALUE, oldValue == null ? NO_VALUE : oldValue) + .withUntypedValue(VALUE_KEY_NEW_VALUE, newValue) + .withSeverity(TypedValue.TRACE_SEVERITY) + .build()); + } catch (Exception e) { + notEditableEquipments.add(equipment.getId()); + equipmentNotModifiedCount += 1; + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_EQUIPMENT_MODIFIED_REPORT_EXCEPTION, + " Cannot modify equipment ${" + VALUE_KEY_EQUIPMENT_NAME + "} : ${" + VALUE_KEY_ERROR_MESSAGE + "}") + .withUntypedValue(VALUE_KEY_EQUIPMENT_NAME, equipment.getId()) + .withUntypedValue(VALUE_KEY_ERROR_MESSAGE, e.getMessage()) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } + } + + private Map getFilters() { + return getAssignmentInfosList().stream() + .flatMap(v -> v.getFilters().stream()) + .filter(distinctByKey(FilterInfos::getId)) + .collect(Collectors.toMap(FilterInfos::getId, FilterInfos::getName)); + } + + private void applyOnFilterEquipments(Network network, + Map filterUuidEquipmentsMap, + List reports, + AbstractAssignmentInfos abstractAssignmentInfos, + FilterInfos filterInfos) { + FilterEquipments filterEquipments = filterUuidEquipmentsMap.get(filterInfos.getId()); + + if (CollectionUtils.isEmpty(filterEquipments.getIdentifiableAttributes())) { + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_BY_FILTER_MODIFICATION_NOT_FOUND, "No equipments were found for filter ${" + VALUE_KEY_FILTER_NAME + "}") + .withUntypedValue(VALUE_KEY_FILTER_NAME, filterInfos.getName()) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } else { + equipmentCount += filterEquipments.getIdentifiableAttributes().size(); + if (!CollectionUtils.isEmpty(filterEquipments.getNotFoundEquipments())) { + equipmentNotFoundCount += filterEquipments.getNotFoundEquipments().size(); + } + List notEditableEquipments = new ArrayList<>(); + List equipmentsReport = new ArrayList<>(); + filterEquipments.getIdentifiableAttributes() + .stream() + .map(attributes -> network.getIdentifiable(attributes.getId())) + .filter(equipment -> { + boolean isEditableEquipment = isEquipmentEditable(equipment, abstractAssignmentInfos, equipmentsReport); + if (!isEditableEquipment) { + notEditableEquipments.add(equipment.getId()); + equipmentNotModifiedCount += 1; + } + return isEditableEquipment; + }) + .forEach(equipment -> applyModification(equipment, abstractAssignmentInfos, equipmentsReport, notEditableEquipments)); + + createAssignmentReports(reports, abstractAssignmentInfos, filterInfos, filterEquipments, notEditableEquipments); + + reports.addAll(equipmentsReport); + } + } + +} diff --git a/src/main/java/org/gridsuite/modification/server/modifications/byfilter/ByFormulaModification.java b/src/main/java/org/gridsuite/modification/server/modifications/byfilter/ByFormulaModification.java new file mode 100644 index 000000000..d8071d983 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/modifications/byfilter/ByFormulaModification.java @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.modifications.byfilter; + +import com.powsybl.commons.report.ReportNode; +import com.powsybl.commons.report.TypedValue; +import com.powsybl.iidm.network.Identifiable; +import com.powsybl.iidm.network.IdentifiableType; +import org.gridsuite.modification.server.NetworkModificationException; +import org.gridsuite.modification.server.dto.ByFormulaModificationInfos; +import org.gridsuite.modification.server.dto.ModificationInfos; +import org.gridsuite.modification.server.dto.byfilter.AbstractAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.formula.FormulaInfos; +import org.gridsuite.modification.server.dto.byfilter.formula.Operator; + +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.List; + +import static org.gridsuite.modification.server.NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR; + +/** + * @author Thang PHAM + */ +public class ByFormulaModification extends AbstractModificationByAssignment { + private final ByFormulaModificationInfos modificationInfos; + + public ByFormulaModification(ByFormulaModificationInfos modificationInfos) { + super(); + this.modificationInfos = modificationInfos; + } + + @Override + public String getModificationTypeLabel() { + return "formula"; + } + + @Override + public ModificationInfos getModificationInfos() { + return modificationInfos; + } + + @Override + public IdentifiableType getEquipmentType() { + return modificationInfos.getIdentifiableType(); + } + + @Override + public List getAssignmentInfosList() { + return Collections.unmodifiableList(modificationInfos.getFormulaInfosList()); + } + + @Override + public NetworkModificationException.Type getExceptionType() { + return BY_FORMULA_MODIFICATION_ERROR; + } + + @Override + protected boolean preCheckValue(Identifiable equipment, AbstractAssignmentInfos abstractAssignmentInfos, List reports, List notEditableEquipments) { + FormulaInfos formulaInfos = (FormulaInfos) abstractAssignmentInfos; + Double value1 = formulaInfos.getFieldOrValue1().getRefOrValue(equipment); + Double value2 = formulaInfos.getFieldOrValue2().getRefOrValue(equipment); + if (value1 == null || Double.isNaN(value1) || value2 == null || Double.isNaN(value2)) { + equipmentNotModifiedCount += 1; + notEditableEquipments.add(equipment.getId()); + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_EQUIPMENT_MODIFIED_ERROR, " Cannot modify equipment ${" + + VALUE_KEY_EQUIPMENT_NAME + "} : At least one of the value or referenced field is null") + .withUntypedValue(VALUE_KEY_EQUIPMENT_NAME, equipment.getId()) + .withSeverity(TypedValue.TRACE_SEVERITY) + .build()); + return false; + } + + if (value2 == 0 && formulaInfos.getOperator() == Operator.DIVISION) { + equipmentNotModifiedCount += 1; + notEditableEquipments.add(equipment.getId()); + reports.add(ReportNode.newRootReportNode() + .withMessageTemplate(REPORT_KEY_EQUIPMENT_MODIFIED_ERROR, " Cannot modify equipment ${" + + VALUE_KEY_EQUIPMENT_NAME + "} : The value or referenced field of the second operand in the division operator is zero") + .withUntypedValue(VALUE_KEY_EQUIPMENT_NAME, equipment.getId()) + .withSeverity(TypedValue.TRACE_SEVERITY) + .build()); + return false; + } + return true; + } + + @Override + protected String getNewValue(Identifiable equipment, AbstractAssignmentInfos abstractAssignmentInfos) { + FormulaInfos formulaInfos = (FormulaInfos) abstractAssignmentInfos; + Double value1 = formulaInfos.getFieldOrValue1().getRefOrValue(equipment); + Double value2 = formulaInfos.getFieldOrValue2().getRefOrValue(equipment); + return applyOperation(formulaInfos.getOperator(), value1, value2).toString(); + } + + private Double applyOperation(Operator operator, @Nonnull Double value1, @Nonnull Double value2) { + return switch (operator) { + case ADDITION -> value1 + value2; + case SUBTRACTION -> value1 - value2; + case MULTIPLICATION -> value1 * value2; + case DIVISION -> value1 / value2; + case PERCENTAGE -> value1 * (value2 / 100); + }; + } +} diff --git a/src/main/java/org/gridsuite/modification/server/modifications/byfilter/ModificationByAssignment.java b/src/main/java/org/gridsuite/modification/server/modifications/byfilter/ModificationByAssignment.java new file mode 100644 index 000000000..421e6656f --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/modifications/byfilter/ModificationByAssignment.java @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.modifications.byfilter; + +import com.powsybl.commons.report.ReportNode; +import com.powsybl.iidm.network.Identifiable; +import com.powsybl.iidm.network.IdentifiableType; +import org.gridsuite.modification.server.NetworkModificationException; +import org.gridsuite.modification.server.dto.ModificationByAssignmentInfos; +import org.gridsuite.modification.server.dto.ModificationInfos; +import org.gridsuite.modification.server.dto.byfilter.AbstractAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.DataType; +import org.gridsuite.modification.server.dto.byfilter.assignment.AssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.PropertyAssignmentInfos; + +import java.util.Collections; +import java.util.List; + +import static org.gridsuite.modification.server.NetworkModificationException.Type.MODIFICATION_BY_ASSIGNMENT_ERROR; + +/** + * @author Thang PHAM + */ +public class ModificationByAssignment extends AbstractModificationByAssignment { + private final ModificationByAssignmentInfos modificationInfos; + + public ModificationByAssignment(ModificationByAssignmentInfos modificationInfos) { + super(); + this.modificationInfos = modificationInfos; + } + + @Override + public String getModificationTypeLabel() { + return "assignment"; + } + + @Override + public ModificationInfos getModificationInfos() { + return modificationInfos; + } + + @Override + public IdentifiableType getEquipmentType() { + return modificationInfos.getEquipmentType(); + } + + @Override + public List getAssignmentInfosList() { + return Collections.unmodifiableList(modificationInfos.getAssignmentInfosList()); + } + + @Override + public NetworkModificationException.Type getExceptionType() { + return MODIFICATION_BY_ASSIGNMENT_ERROR; + } + + @Override + protected boolean isEquipmentEditable(Identifiable equipment, AbstractAssignmentInfos abstractAssignmentInfos, List equipmentsReport) { + AssignmentInfos assignmentInfos = (AssignmentInfos) abstractAssignmentInfos; + if (assignmentInfos.getDataType() == DataType.PROPERTY) { + return true; + } else { + return super.isEquipmentEditable(equipment, abstractAssignmentInfos, equipmentsReport); + } + } + + @Override + protected boolean preCheckValue(Identifiable equipment, AbstractAssignmentInfos abstractAssignmentInfos, List reports, List notEditableEquipments) { + return true; + } + + @Override + protected String getOldValue(Identifiable equipment, AbstractAssignmentInfos abstractAssignmentInfos) { + AssignmentInfos assignmentInfos = (AssignmentInfos) abstractAssignmentInfos; + if (assignmentInfos.getDataType() == DataType.PROPERTY) { + return equipment.getProperty(((PropertyAssignmentInfos) assignmentInfos).getPropertyName()); + } else { + return super.getOldValue(equipment, abstractAssignmentInfos); + } + } + + @Override + protected String getNewValue(Identifiable equipment, AbstractAssignmentInfos abstractAssignmentInfos) { + AssignmentInfos assignmentInfos = (AssignmentInfos) abstractAssignmentInfos; + if (assignmentInfos.getValue() == null) { + throw new NetworkModificationException(MODIFICATION_BY_ASSIGNMENT_ERROR, "Missing a value in the assignment"); + } + return assignmentInfos.getValue().toString(); + } + + @Override + protected String applyValue(Identifiable equipment, AbstractAssignmentInfos abstractAssignmentInfos) { + AssignmentInfos assignmentInfos = (AssignmentInfos) abstractAssignmentInfos; + if (assignmentInfos.getDataType() == DataType.PROPERTY) { + String newValue = getNewValue(equipment, abstractAssignmentInfos); + equipment.setProperty(((PropertyAssignmentInfos) assignmentInfos).getPropertyName(), newValue); + return newValue; + } else { + return super.applyValue(equipment, abstractAssignmentInfos); + } + } +} diff --git a/src/main/resources/db/changelog/changesets/changelog_20240912T130742Z.xml b/src/main/resources/db/changelog/changesets/changelog_20240912T130742Z.xml new file mode 100644 index 000000000..d7e93035e --- /dev/null +++ b/src/main/resources/db/changelog/changesets/changelog_20240912T130742Z.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 32b8d57e2..1e8120d72 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -308,4 +308,7 @@ databaseChangeLog: relativeToChangelogFile: true - include: file: changesets/changelog_20240904T211456Z.xml - relativeToChangelogFile: true \ No newline at end of file + relativeToChangelogFile: true + - include: + file: changesets/changelog_20240912T130742Z.xml + relativeToChangelogFile: true diff --git a/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/AbstractModificationByAssignmentTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/AbstractModificationByAssignmentTest.java new file mode 100644 index 000000000..9bb0958e2 --- /dev/null +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/AbstractModificationByAssignmentTest.java @@ -0,0 +1,263 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.modifications.byfilter.assignment; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.matching.StringValuePattern; +import com.powsybl.iidm.network.IdentifiableType; +import com.powsybl.iidm.network.Network; +import org.gridsuite.filter.AbstractFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; +import org.gridsuite.filter.utils.EquipmentType; +import org.gridsuite.modification.server.dto.FilterInfos; +import org.gridsuite.modification.server.dto.ModificationByAssignmentInfos; +import org.gridsuite.modification.server.dto.NetworkModificationResult; +import org.gridsuite.modification.server.dto.byfilter.DataType; +import org.gridsuite.modification.server.dto.byfilter.assignment.AssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.DoubleAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.PropertyAssignmentInfos; +import org.gridsuite.modification.server.impacts.AbstractBaseImpact; +import org.gridsuite.modification.server.modifications.AbstractNetworkModificationTest; +import org.gridsuite.modification.server.service.FilterService; +import org.gridsuite.modification.server.utils.NetworkCreation; +import org.junit.Before; +import org.junit.Test; +import org.junit.jupiter.api.Tag; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MvcResult; + +import java.util.*; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.gridsuite.modification.server.Impacts.TestImpactUtils.createCollectionElementImpact; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * @author Thang PHAM + */ +@Tag("IntegrationTest") +public abstract class AbstractModificationByAssignmentTest extends AbstractNetworkModificationTest { + protected static final UUID FILTER_ID_1 = UUID.randomUUID(); + protected static final UUID FILTER_ID_2 = UUID.randomUUID(); + protected static final UUID FILTER_ID_3 = UUID.randomUUID(); + protected static final UUID FILTER_ID_4 = UUID.randomUUID(); + protected static final UUID FILTER_ID_5 = UUID.randomUUID(); + protected static final UUID FILTER_ID_6 = UUID.randomUUID(); + protected static final UUID FILTER_WITH_ALL_WRONG_IDS = UUID.randomUUID(); + protected static final UUID FILTER_WITH_ONE_WRONG_ID = UUID.randomUUID(); + protected final FilterInfos filter1 = new FilterInfos(FILTER_ID_1, "filter1"); + protected final FilterInfos filter2 = new FilterInfos(FILTER_ID_2, "filter2"); + protected final FilterInfos filter3 = new FilterInfos(FILTER_ID_3, "filter3"); + protected final FilterInfos filter4 = new FilterInfos(FILTER_ID_4, "filter4"); + protected final FilterInfos filter5 = new FilterInfos(FILTER_ID_5, "filter5"); + protected final FilterInfos filter6 = new FilterInfos(FILTER_ID_6, "filter6"); + protected final FilterInfos filterWithOneWrongId = new FilterInfos(FILTER_WITH_ONE_WRONG_ID, "filterWithOneWrongId"); + + public static final String PATH = "/v1/filters/metadata"; + + @Override + protected void assertResultImpacts(List impacts) { + assertThat(impacts).containsExactly(createCollectionElementImpact(getIdentifiableType())); + } + + @Before + public void specificSetUp() { + FilterService.setFilterServerBaseUri(wireMockServer.baseUrl()); + + getNetwork().getVariantManager().setWorkingVariant("variant_1"); + createEquipments(); + } + + @Test + public void testByModificationError() throws Exception { + //Test with modification = null + mockMvc.perform(post(getNetworkModificationUri()).content(mapper.writeValueAsString(null)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + + // Test with empty list of assignment + checkCreationApplicationStatus(List.of(), NetworkModificationResult.ApplicationStatus.WITH_ERRORS); + + // Test with empty list of filters in assignment + List> assignmentsWithNoFilters = getAssignmentInfos().stream().peek(assignmentInfos -> assignmentInfos.setFilters(List.of())).toList(); + checkCreationApplicationStatus(assignmentsWithNoFilters, NetworkModificationResult.ApplicationStatus.WITH_ERRORS); + + // Test with editedField = null + AssignmentInfos assignmentWithNoEditedField = DoubleAssignmentInfos.builder() + .value(50.) + .filters(List.of()) + .build(); + checkCreationApplicationStatus(List.of(assignmentWithNoEditedField), NetworkModificationResult.ApplicationStatus.WITH_ERRORS); + } + + protected void checkCreateWithWarning(List> assignments, List existingEquipmentList) throws Exception { + AbstractFilter filter = getFilterEquipments(FILTER_WITH_ONE_WRONG_ID, existingEquipmentList); + + UUID stubId = wireMockServer.stubFor(WireMock.get(WireMock.urlMatching("/v1/filters/metadata\\?ids=" + FILTER_WITH_ONE_WRONG_ID)) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(List.of(filter))) + .withHeader("Content-Type", "application/json"))).getId(); + + checkCreationApplicationStatus(assignments, NetworkModificationResult.ApplicationStatus.WITH_WARNINGS); + + wireMockUtils.verifyGetRequest(stubId, PATH, handleQueryParams(List.of(FILTER_WITH_ONE_WRONG_ID)), false); + } + + protected void checkCreateWithError(List> assignments, List filterEquipments) throws Exception { + String filterIds = filterEquipments.stream() + .map(AbstractFilter::getId) + .map(UUID::toString) + .collect(Collectors.joining(",")); + + UUID stubId = wireMockServer.stubFor(WireMock.get(WireMock.urlMatching("/v1/filters/metadata\\?ids=" + filterIds)) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(filterEquipments)) + .withHeader("Content-Type", "application/json"))).getId(); + + checkCreationApplicationStatus(assignments, NetworkModificationResult.ApplicationStatus.WITH_ERRORS); + + wireMockUtils.verifyGetRequest(stubId, + PATH, + handleQueryParams(filterEquipments.stream().map(AbstractFilter::getId).toList()), + false); + } + + @Test + public void testModificationWithAllWrongEquipmentIds() throws Exception { + AbstractFilter filter = getFilterEquipments(FILTER_WITH_ALL_WRONG_IDS, List.of()); + + List> assignmentsWithWrongFilter = getAssignmentInfos().stream() + .peek(assignmentInfos -> assignmentInfos.setFilters(List.of(new FilterInfos(FILTER_WITH_ALL_WRONG_IDS, "filterWithWrongId")))) + .toList(); + + UUID stubId = wireMockServer.stubFor(WireMock.get(WireMock.urlMatching("/v1/filters/metadata\\?ids=" + FILTER_WITH_ALL_WRONG_IDS)) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(List.of(filter))) + .withHeader("Content-Type", "application/json"))).getId(); + + checkCreationApplicationStatus(assignmentsWithWrongFilter, NetworkModificationResult.ApplicationStatus.WITH_ERRORS); + + wireMockUtils.verifyGetRequest(stubId, PATH, handleQueryParams(List.of(FILTER_WITH_ALL_WRONG_IDS)), false); + } + + @Test + @Override + public void testCreate() throws Exception { + List filters = getTestFilters(); + UUID stubId = wireMockServer.stubFor(WireMock.get(WireMock.urlMatching(getPath(true) + ".{2,}")) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(filters)) + .withHeader("Content-Type", "application/json"))).getId(); + + super.testCreate(); + + wireMockUtils.verifyGetRequest(stubId, PATH, handleQueryParams(filters.stream().map(AbstractFilter::getId).toList()), false); + } + + @Test + @Override + public void testCopy() throws Exception { + List filters = getTestFilters(); + UUID stubId = wireMockServer.stubFor(WireMock.get(WireMock.urlMatching(getPath(true) + ".{2,}")) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(filters)) + .withHeader("Content-Type", "application/json"))).getId(); + + super.testCopy(); + + wireMockUtils.verifyGetRequest(stubId, PATH, handleQueryParams(filters.stream().map(AbstractFilter::getId).toList()), false); + } + + protected void checkCreationApplicationStatus(List> assignmentInfos, + NetworkModificationResult.ApplicationStatus applicationStatus) throws Exception { + ModificationByAssignmentInfos modificationByAssignmentInfos = ModificationByAssignmentInfos.builder() + .equipmentType(getIdentifiableType()) + .assignmentInfosList(assignmentInfos) + .build(); + String modificationToCreateJson = mapper.writeValueAsString(modificationByAssignmentInfos); + + MvcResult mvcResult = mockMvc.perform(post(getNetworkModificationUri()).content(modificationToCreateJson).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + + Optional networkModificationResult = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + assertTrue(networkModificationResult.isPresent()); + assertEquals(applicationStatus, networkModificationResult.get().getApplicationStatus()); + } + + @Override + protected Network createNetwork(UUID networkUuid) { + return NetworkCreation.create(networkUuid, true); + } + + @Override + protected ModificationByAssignmentInfos buildModification() { + return ModificationByAssignmentInfos.builder() + .equipmentType(getIdentifiableType()) + .assignmentInfosList(getAssignmentInfos()) + .stashed(false) + .build(); + } + + @Override + protected ModificationByAssignmentInfos buildModificationUpdate() { + return ModificationByAssignmentInfos.builder() + .equipmentType(getIdentifiableType()) + .assignmentInfosList(getUpdatedAssignmentInfos()) + .stashed(false) + .build(); + } + + protected IdentifierListFilterEquipmentAttributes getIdentifiableAttributes(String id, Double distributionKey) { + return new IdentifierListFilterEquipmentAttributes(id, distributionKey); + } + + protected AbstractFilter getFilterEquipments(UUID filterID, List identifiableAttributes) { + return IdentifierListFilter.builder().id(filterID).modificationDate(new Date()).equipmentType(getEquipmentType()) + .filterEquipmentsAttributes(identifiableAttributes) + .build(); + } + + Map handleQueryParams(List filterIds) { + return Map.of("ids", WireMock.matching(filterIds.stream().map(uuid -> ".+").collect(Collectors.joining(",")))); + } + + String getPath(boolean isRegexPath) { + if (isRegexPath) { + return "/v1/filters/metadata\\?ids="; + } + return "/v1/filters/metadata?ids="; + } + + protected abstract void createEquipments(); + + protected abstract List getTestFilters(); + + protected List> getAssignmentInfos() { + PropertyAssignmentInfos spyAssignmentInfos = spy(PropertyAssignmentInfos.builder() + .editedField(DataType.PROPERTY.name()) + .propertyName("propertyName") + .value("propertyValue") + .filters(List.of(filter1)) + .build()); + doReturn(DataType.PROPERTY).when(spyAssignmentInfos).getDataType(); + return new ArrayList<>(List.of(spyAssignmentInfos)); + } + + protected abstract List> getUpdatedAssignmentInfos(); + + protected abstract IdentifiableType getIdentifiableType(); + + protected abstract EquipmentType getEquipmentType(); +} diff --git a/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/BatteryModificationByAssignmentTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/BatteryModificationByAssignmentTest.java new file mode 100644 index 000000000..ed88c74f2 --- /dev/null +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/BatteryModificationByAssignmentTest.java @@ -0,0 +1,214 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.modifications.byfilter.assignment; + +import com.powsybl.iidm.network.IdentifiableType; +import com.powsybl.iidm.network.extensions.ActivePowerControl; +import com.powsybl.iidm.network.extensions.ActivePowerControlAdder; +import org.gridsuite.filter.AbstractFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; +import org.gridsuite.filter.utils.EquipmentType; +import org.gridsuite.modification.server.dto.byfilter.assignment.AssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.DoubleAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.BatteryField; +import org.junit.Test; + +import java.util.Date; +import java.util.List; + +import static org.gridsuite.modification.server.utils.NetworkUtil.createBattery; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author Thang PHAM + */ +public class BatteryModificationByAssignmentTest extends AbstractModificationByAssignmentTest { + private static final String BATTERY_ID_1 = "v3Battery"; + private static final String BATTERY_ID_2 = "battery2"; + private static final String BATTERY_ID_3 = "battery3"; + private static final String BATTERY_ID_4 = "battery4"; + private static final String BATTERY_ID_5 = "battery5"; + private static final String BATTERY_ID_6 = "battery6"; + + @Test + public void testCreateWithWarning() throws Exception { + IdentifierListFilterEquipmentAttributes identifiableAttributes = getIdentifiableAttributes(BATTERY_ID_1, 1.0); + IdentifierListFilterEquipmentAttributes wrongIdAttributes = getIdentifiableAttributes("wrongId", 1.0); + + DoubleAssignmentInfos assignmentInfos = DoubleAssignmentInfos.builder() + .filters(List.of(filterWithOneWrongId)) + .editedField(BatteryField.ACTIVE_POWER_SET_POINT.name()) + .value(55.) + .build(); + + checkCreateWithWarning(List.of(assignmentInfos), List.of(identifiableAttributes, wrongIdAttributes)); + assertEquals(55, getNetwork().getBattery(BATTERY_ID_1).getTargetP(), 0); + } + + @Override + protected void createEquipments() { + getNetwork().getBattery(BATTERY_ID_1).setTargetP(100).setMaxP(500).setMinP(0).setTargetQ(80); + getNetwork().getBattery(BATTERY_ID_1).newExtension(ActivePowerControlAdder.class).withDroop(1).add(); + + createBattery(getNetwork().getVoltageLevel("v2"), BATTERY_ID_2, "v2Battery2", 20, 50, 2000, 200, 50); + createBattery(getNetwork().getVoltageLevel("v3"), BATTERY_ID_3, "v3Battery3", 30, 70, 400, 300, 50); + + createBattery(getNetwork().getVoltageLevel("v4"), BATTERY_ID_4, "v4Battery4", 40, 25, 350, 70, 50); + + createBattery(getNetwork().getVoltageLevel("v5"), BATTERY_ID_5, "v5Battery5", 50, 50, 600, 55, 140); + getNetwork().getBattery(BATTERY_ID_5).newExtension(ActivePowerControlAdder.class).withDroop(4).add(); + + createBattery(getNetwork().getVoltageLevel("v6"), BATTERY_ID_6, "v6Battery6", 60, 200, 700, 250, 210); + } + + @Override + protected List getTestFilters() { + IdentifierListFilter filter1 = IdentifierListFilter.builder().id(FILTER_ID_1).modificationDate(new Date()).equipmentType(EquipmentType.BATTERY) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(BATTERY_ID_1, 1.0), + new IdentifierListFilterEquipmentAttributes(BATTERY_ID_2, 2.0))) + .build(); + IdentifierListFilter filter2 = IdentifierListFilter.builder().id(FILTER_ID_2).modificationDate(new Date()).equipmentType(EquipmentType.BATTERY) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(BATTERY_ID_3, 2.0), + new IdentifierListFilterEquipmentAttributes(BATTERY_ID_4, 5.0))) + .build(); + IdentifierListFilter filter3 = IdentifierListFilter.builder().id(FILTER_ID_3).modificationDate(new Date()).equipmentType(EquipmentType.BATTERY) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(BATTERY_ID_5, 6.0), + new IdentifierListFilterEquipmentAttributes(BATTERY_ID_6, 7.0))) + .build(); + IdentifierListFilter filter4 = IdentifierListFilter.builder().id(FILTER_ID_4).modificationDate(new Date()).equipmentType(EquipmentType.BATTERY) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(BATTERY_ID_1, 1.0), + new IdentifierListFilterEquipmentAttributes(BATTERY_ID_5, 6.0))) + .build(); + IdentifierListFilter filter5 = IdentifierListFilter.builder().id(FILTER_ID_5).modificationDate(new Date()).equipmentType(EquipmentType.BATTERY) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(BATTERY_ID_2, 2.0), + new IdentifierListFilterEquipmentAttributes(BATTERY_ID_3, 3.0))) + .build(); + + return List.of(filter1, filter2, filter3, filter4, filter5); + } + + @Override + protected List> getAssignmentInfos() { + DoubleAssignmentInfos assignmentInfos1 = DoubleAssignmentInfos.builder() + .filters(List.of(filter1, filter2)) + .editedField(BatteryField.MAXIMUM_ACTIVE_POWER.name()) + .value(80.) + .build(); + + DoubleAssignmentInfos assignmentInfos2 = DoubleAssignmentInfos.builder() + .filters(List.of(filter3)) + .editedField(BatteryField.MINIMUM_ACTIVE_POWER.name()) + .value(30.) + .build(); + + DoubleAssignmentInfos assignmentInfos3 = DoubleAssignmentInfos.builder() + .filters(List.of(filter5)) + .editedField(BatteryField.ACTIVE_POWER_SET_POINT.name()) + .value(75.) + .build(); + + DoubleAssignmentInfos assignmentInfos4 = DoubleAssignmentInfos.builder() + .filters(List.of(filter4)) + .editedField(BatteryField.REACTIVE_POWER_SET_POINT.name()) + .value(2.) + .build(); + + DoubleAssignmentInfos assignmentInfos5 = DoubleAssignmentInfos.builder() + .filters(List.of(filter4)) + .editedField(BatteryField.DROOP.name()) + .value(2.) + .build(); + + List> infosList = super.getAssignmentInfos(); + infosList.addAll(List.of(assignmentInfos1, assignmentInfos2, assignmentInfos3, assignmentInfos4, assignmentInfos5)); + + return infosList; + } + + @Override + protected List> getUpdatedAssignmentInfos() { + DoubleAssignmentInfos assignmentInfos1 = DoubleAssignmentInfos.builder() + .filters(List.of(filter1, filter2)) + .editedField(BatteryField.MAXIMUM_ACTIVE_POWER.name()) + .value(200.) + .build(); + + DoubleAssignmentInfos assignmentInfos2 = DoubleAssignmentInfos.builder() + .filters(List.of(filter3)) + .editedField(BatteryField.MINIMUM_ACTIVE_POWER.name()) + .value(35.) + .build(); + + DoubleAssignmentInfos assignmentInfos3 = DoubleAssignmentInfos.builder() + .filters(List.of(filter3)) + .editedField(BatteryField.ACTIVE_POWER_SET_POINT.name()) + .value(10.) + .build(); + + return List.of(assignmentInfos1, assignmentInfos2, assignmentInfos3); + } + + @Override + protected void assertAfterNetworkModificationCreation() { + assertEquals(80, getNetwork().getBattery(BATTERY_ID_1).getMaxP(), 0); + assertEquals(2, getNetwork().getBattery(BATTERY_ID_1).getTargetQ(), 0); + ActivePowerControl activePowerControl1 = getNetwork().getBattery(BATTERY_ID_1).getExtension(ActivePowerControl.class); + assertNotNull(activePowerControl1); + assertEquals(2, activePowerControl1.getDroop(), 0); + + assertEquals(80, getNetwork().getBattery(BATTERY_ID_2).getMaxP(), 0); + assertEquals(75, getNetwork().getBattery(BATTERY_ID_2).getTargetP(), 0); + assertEquals(80, getNetwork().getBattery(BATTERY_ID_3).getMaxP(), 0); + assertEquals(75, getNetwork().getBattery(BATTERY_ID_3).getTargetP(), 0); + assertEquals(80, getNetwork().getBattery(BATTERY_ID_4).getMaxP(), 0); + + assertEquals(30, getNetwork().getBattery(BATTERY_ID_5).getMinP(), 0); + assertEquals(2, getNetwork().getBattery(BATTERY_ID_5).getTargetQ(), 0); + ActivePowerControl activePowerControl5 = getNetwork().getBattery(BATTERY_ID_5).getExtension(ActivePowerControl.class); + assertNotNull(activePowerControl5); + assertEquals(2, activePowerControl5.getDroop(), 0); + + assertEquals(30, getNetwork().getBattery(BATTERY_ID_6).getMinP(), 0); + } + + @Override + protected void assertAfterNetworkModificationDeletion() { + assertEquals(500, getNetwork().getBattery(BATTERY_ID_1).getMaxP(), 0); + assertEquals(80, getNetwork().getBattery(BATTERY_ID_1).getTargetQ(), 0); + ActivePowerControl activePowerControl1 = getNetwork().getBattery(BATTERY_ID_1).getExtension(ActivePowerControl.class); + assertNotNull(activePowerControl1); + assertEquals(1, activePowerControl1.getDroop(), 0); + + assertEquals(2000, getNetwork().getBattery(BATTERY_ID_2).getMaxP(), 0); + assertEquals(200, getNetwork().getBattery(BATTERY_ID_2).getTargetP(), 0); + assertEquals(400, getNetwork().getBattery(BATTERY_ID_3).getMaxP(), 0); + assertEquals(300, getNetwork().getBattery(BATTERY_ID_3).getTargetP(), 0); + assertEquals(350, getNetwork().getBattery(BATTERY_ID_4).getMaxP(), 0); + + assertEquals(50, getNetwork().getBattery(BATTERY_ID_5).getMinP(), 0); + assertEquals(140, getNetwork().getBattery(BATTERY_ID_5).getTargetQ(), 0); + ActivePowerControl activePowerControl5 = getNetwork().getBattery(BATTERY_ID_5).getExtension(ActivePowerControl.class); + assertNotNull(activePowerControl5); + assertEquals(4, activePowerControl5.getDroop(), 0); + + assertEquals(200, getNetwork().getBattery(BATTERY_ID_6).getMinP(), 0); + } + + @Override + protected IdentifiableType getIdentifiableType() { + return IdentifiableType.BATTERY; + } + + @Override + protected EquipmentType getEquipmentType() { + return EquipmentType.BATTERY; + } + +} diff --git a/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/GeneratorModificationByAssignmentTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/GeneratorModificationByAssignmentTest.java new file mode 100644 index 000000000..f4c724173 --- /dev/null +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/GeneratorModificationByAssignmentTest.java @@ -0,0 +1,441 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.modifications.byfilter.assignment; + +import com.powsybl.iidm.network.Generator; +import com.powsybl.iidm.network.IdentifiableType; +import com.powsybl.iidm.network.extensions.*; +import org.gridsuite.filter.AbstractFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; +import org.gridsuite.filter.utils.EquipmentType; +import org.gridsuite.modification.server.dto.byfilter.assignment.AssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.BooleanAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.DoubleAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.GeneratorField; +import org.junit.Test; +import org.junit.jupiter.api.Tag; + +import java.util.Date; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.gridsuite.modification.server.utils.NetworkUtil.createGenerator; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author Thang PHAM + */ +@Tag("IntegrationTest") +public class GeneratorModificationByAssignmentTest extends AbstractModificationByAssignmentTest { + private static final String GENERATOR_ID_1 = "idGenerator"; + private static final String GENERATOR_ID_2 = "v5generator"; + private static final String GENERATOR_ID_3 = "v6generator"; + private static final String GENERATOR_ID_4 = "gen4"; + private static final String GENERATOR_ID_5 = "gen5"; + private static final String GENERATOR_ID_6 = "gen6"; + private static final String GENERATOR_ID_7 = "gen7"; + private static final String GENERATOR_ID_8 = "gen8"; + private static final String GENERATOR_ID_9 = "gen9"; + private static final String GENERATOR_ID_10 = "gen10"; + + @Test + public void testCreateWithWarning() throws Exception { + IdentifierListFilterEquipmentAttributes identifiableAttributes = getIdentifiableAttributes(GENERATOR_ID_1, 1.0); + IdentifierListFilterEquipmentAttributes wrongIdAttributes = getIdentifiableAttributes("wrongId", 1.0); + + DoubleAssignmentInfos assignmentInfos = DoubleAssignmentInfos.builder() + .filters(List.of(filterWithOneWrongId)) + .editedField(GeneratorField.ACTIVE_POWER_SET_POINT.name()) + .value(55.) + .build(); + + checkCreateWithWarning(List.of(assignmentInfos), List.of(identifiableAttributes, wrongIdAttributes)); + assertEquals(55, getNetwork().getGenerator(GENERATOR_ID_1).getTargetP(), 0); + } + + protected void createEquipments() { + getNetwork().getGenerator(GENERATOR_ID_1) + .setTargetP(100) + .setMaxP(500) + .setMinP(0) + .setTargetV(10) + .setTargetQ(20) + .newExtension(GeneratorStartupAdder.class) + .withMarginalCost(30.) + .withPlannedOutageRate(25.) + .withPlannedActivePowerSetpoint(40.) + .withForcedOutageRate(55.) + .add(); + + getNetwork().getGenerator(GENERATOR_ID_2) + .setTargetP(200) + .setMaxP(2000) + .setMinP(50) + .setTargetV(10) + .setTargetQ(20) + .newExtension(GeneratorStartupAdder.class) + .withMarginalCost(30.) + .withPlannedOutageRate(25.) + .withPlannedActivePowerSetpoint(40.) + .withForcedOutageRate(55.) + .add(); + + getNetwork().getGenerator(GENERATOR_ID_3) + .setTargetP(300) + .setMaxP(2000) + .setMinP(70) + .newExtension(GeneratorShortCircuitAdder.class) + .withDirectTransX(40.) + .withStepUpTransformerX(38.) + .add(); + + createGenerator(getNetwork().getVoltageLevel("v1"), GENERATOR_ID_4, 3, 400, 1.0, "cn10", 11, ConnectablePosition.Direction.TOP, 700, 110); + getNetwork().getGenerator(GENERATOR_ID_4) + .newExtension(GeneratorShortCircuitAdder.class) + .withDirectTransX(46.) + .withStepUpTransformerX(50.) + .add(); + + createGenerator(getNetwork().getVoltageLevel("v1"), GENERATOR_ID_5, 20, 200, 1.0, "cn10", 12, ConnectablePosition.Direction.TOP, 2000, 50); + getNetwork().getGenerator(GENERATOR_ID_5).newExtension(ActivePowerControlAdder.class).withDroop(2).add(); + + createGenerator(getNetwork().getVoltageLevel("v2"), GENERATOR_ID_6, 11, 100, 1.0, "cn10", 13, ConnectablePosition.Direction.TOP, 500, 20); + getNetwork().getGenerator(GENERATOR_ID_6).newExtension(ActivePowerControlAdder.class).withDroop(3).add(); + + createGenerator(getNetwork().getVoltageLevel("v6"), GENERATOR_ID_7, 10, 200, 1.0, "cn10", 14, ConnectablePosition.Direction.TOP, 2000, 50); + getNetwork().getGenerator(GENERATOR_ID_7).newExtension(CoordinatedReactiveControlAdder.class) + .withQPercent(6) + .add(); + getNetwork().getGenerator(GENERATOR_ID_7).newExtension(GeneratorStartupAdder.class).withMarginalCost(50).add(); + + createGenerator(getNetwork().getVoltageLevel("v3"), GENERATOR_ID_8, 10, 100, 1.0, "cn10", 15, ConnectablePosition.Direction.TOP, 500, 20); + getNetwork().getGenerator(GENERATOR_ID_8).newExtension(CoordinatedReactiveControlAdder.class) + .withQPercent(12) + .add(); + getNetwork().getGenerator(GENERATOR_ID_8).newExtension(GeneratorStartupAdder.class).withMarginalCost(60).add(); + + createGenerator(getNetwork().getVoltageLevel("v4"), GENERATOR_ID_9, 10, 200, 1.0, "cn10", 16, ConnectablePosition.Direction.TOP, 2000, 50); + getNetwork().getGenerator(GENERATOR_ID_9).setRatedS(60.); + + createGenerator(getNetwork().getVoltageLevel("v5"), GENERATOR_ID_10, 10, 100, 1.0, "cn10", 17, ConnectablePosition.Direction.TOP, 500, 20); + getNetwork().getGenerator(GENERATOR_ID_10).setRatedS(30.); + } + + protected List getTestFilters() { + IdentifierListFilter filter1 = IdentifierListFilter.builder().id(FILTER_ID_1).modificationDate(new Date()).equipmentType(EquipmentType.GENERATOR) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(GENERATOR_ID_1, 1.0), + new IdentifierListFilterEquipmentAttributes(GENERATOR_ID_2, 2.0))) + .build(); + IdentifierListFilter filter2 = IdentifierListFilter.builder().id(FILTER_ID_2).modificationDate(new Date()).equipmentType(EquipmentType.GENERATOR) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(GENERATOR_ID_3, 2.0), + new IdentifierListFilterEquipmentAttributes(GENERATOR_ID_4, 5.0))) + .build(); + IdentifierListFilter filter3 = IdentifierListFilter.builder().id(FILTER_ID_3).modificationDate(new Date()).equipmentType(EquipmentType.GENERATOR) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(GENERATOR_ID_5, 6.0), + new IdentifierListFilterEquipmentAttributes(GENERATOR_ID_6, 7.0))) + .build(); + IdentifierListFilter filter4 = IdentifierListFilter.builder().id(FILTER_ID_4).modificationDate(new Date()).equipmentType(EquipmentType.GENERATOR) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(GENERATOR_ID_7, 3.0), + new IdentifierListFilterEquipmentAttributes(GENERATOR_ID_8, 8.0))) + .build(); + IdentifierListFilter filter5 = IdentifierListFilter.builder().id(FILTER_ID_5).modificationDate(new Date()).equipmentType(EquipmentType.GENERATOR) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(GENERATOR_ID_9, 0.0), + new IdentifierListFilterEquipmentAttributes(GENERATOR_ID_10, 9.0))) + .build(); + + return List.of(filter1, filter2, filter3, filter4, filter5); + } + + @Override + protected List> getAssignmentInfos() { + + DoubleAssignmentInfos assignmentInfos1 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.REACTIVE_POWER_SET_POINT.name()) + .value(50.) + .filters(List.of(filter1, filter2)) + .build(); + + DoubleAssignmentInfos assignmentInfos2 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.DROOP.name()) + .value(2.) + .filters(List.of(filter3)) + .build(); + + DoubleAssignmentInfos assignmentInfos3 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.RATED_NOMINAL_POWER.name()) + .value(2.) + .filters(List.of(filter5)) + .build(); + + DoubleAssignmentInfos assignmentInfos4 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.MARGINAL_COST.name()) + .value(2.) + .filters(List.of(filter1)) + .build(); + + DoubleAssignmentInfos assignmentInfos5 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.VOLTAGE_SET_POINT.name()) + .value(2.) + .filters(List.of(filter4)) + .build(); + + DoubleAssignmentInfos assignmentInfos6 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.PLANNED_ACTIVE_POWER_SET_POINT.name()) + .value(10.) + .filters(List.of(filter1)) + .build(); + + DoubleAssignmentInfos assignmentInfos7 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.MINIMUM_ACTIVE_POWER.name()) + .value(2.) + .filters(List.of(filter1, filter2)) + .build(); + + DoubleAssignmentInfos assignmentInfos8 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.PLANNED_OUTAGE_RATE.name()) + .value(0.1) + .filters(List.of(filter1)) + .build(); + + DoubleAssignmentInfos assignmentInfos9 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.FORCED_OUTAGE_RATE.name()) + .value(0.05) + .filters(List.of(filter1)) + .build(); + + DoubleAssignmentInfos assignmentInfos10 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.MAXIMUM_ACTIVE_POWER.name()) + .value(50.) + .filters(List.of(filter1, filter2, filter3, filter4, filter5)) + .build(); + + DoubleAssignmentInfos assignmentInfos11 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.TRANSIENT_REACTANCE.name()) + .value(0.2) + .filters(List.of(filter2)) + .build(); + + DoubleAssignmentInfos assignmentInfos12 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.STEP_UP_TRANSFORMER_REACTANCE.name()) + .value(0.3) + .filters(List.of(filter2)) + .build(); + + DoubleAssignmentInfos assignmentInfos13 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.Q_PERCENT.name()) + .value(0.25) + .filters(List.of(filter4)) + .build(); + + BooleanAssignmentInfos assignmentInfos14 = BooleanAssignmentInfos.builder() + .editedField(GeneratorField.VOLTAGE_REGULATOR_ON.name()) + .value(true) + .filters(List.of(filter1)) + .build(); + + List> infosList = super.getAssignmentInfos(); + infosList.addAll(List.of( + assignmentInfos1, + assignmentInfos2, + assignmentInfos3, + assignmentInfos4, + assignmentInfos5, + assignmentInfos6, + assignmentInfos7, + assignmentInfos8, + assignmentInfos9, + assignmentInfos10, + assignmentInfos11, + assignmentInfos12, + assignmentInfos13, + assignmentInfos14 + )); + + return infosList; + } + + @Override + protected List> getUpdatedAssignmentInfos() { + DoubleAssignmentInfos assignmentInfos1 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.REACTIVE_POWER_SET_POINT.name()) + .value(2.) + .filters(List.of(filter1, filter2)) + .build(); + + DoubleAssignmentInfos assignmentInfos2 = DoubleAssignmentInfos.builder() + .editedField(GeneratorField.MINIMUM_ACTIVE_POWER.name()) + .value(0.5) + .filters(List.of(filter3)) + .build(); + + return List.of(assignmentInfos1, assignmentInfos2); + } + + @Override + protected void assertAfterNetworkModificationCreation() { + Generator generator1 = getNetwork().getGenerator(GENERATOR_ID_1); + GeneratorStartup generatorStartup1 = generator1.getExtension(GeneratorStartup.class); + assertNotNull(generatorStartup1); + assertThat(generator1.getProperty("propertyName")).isEqualTo("propertyValue"); + assertEquals(100, generator1.getTargetP(), 0); + assertEquals(2, generatorStartup1.getMarginalCost(), 0); + assertEquals(0.1, generatorStartup1.getPlannedOutageRate(), 0); + assertEquals(0.05, generatorStartup1.getForcedOutageRate(), 0); + assertEquals(10, generatorStartup1.getPlannedActivePowerSetpoint(), 0); + assertEquals(50, generator1.getMaxP(), 0); + assertEquals(2, generator1.getMinP(), 0); + assertEquals(true, generator1.isVoltageRegulatorOn()); + + Generator generator2 = getNetwork().getGenerator(GENERATOR_ID_2); + GeneratorStartup generatorStartup2 = generator2.getExtension(GeneratorStartup.class); + assertNotNull(generatorStartup2); + assertThat(generator2.getProperty("propertyName")).isEqualTo("propertyValue"); + assertEquals(200, generator2.getTargetP(), 0); + assertEquals(2, generatorStartup2.getMarginalCost(), 0); + assertEquals(0.1, generatorStartup2.getPlannedOutageRate(), 0); + assertEquals(0.05, generatorStartup2.getForcedOutageRate(), 0); + assertEquals(10, generatorStartup2.getPlannedActivePowerSetpoint(), 0); + assertEquals(50, generator2.getMaxP(), 0); + assertEquals(2, generator2.getMinP(), 0); + + Generator generator3 = getNetwork().getGenerator(GENERATOR_ID_3); + GeneratorShortCircuit generatorShortCircuit3 = generator3.getExtension(GeneratorShortCircuit.class); + assertNotNull(generatorShortCircuit3); + assertEquals(300, generator3.getTargetP(), 0); + assertEquals(0.2, generatorShortCircuit3.getDirectTransX(), 0); + assertEquals(0.3, generatorShortCircuit3.getStepUpTransformerX(), 0); + assertEquals(50, generator3.getMaxP(), 0); + assertEquals(2, generator3.getMinP(), 0); + + Generator generator4 = getNetwork().getGenerator(GENERATOR_ID_4); + GeneratorShortCircuit generatorShortCircuit4 = generator4.getExtension(GeneratorShortCircuit.class); + assertNotNull(generatorShortCircuit4); + assertEquals(0.2, generatorShortCircuit4.getDirectTransX(), 0); + assertEquals(0.3, generatorShortCircuit4.getStepUpTransformerX(), 0); + assertEquals(400, generator4.getTargetP(), 0); + assertEquals(50, generator4.getMaxP(), 0); + assertEquals(2, generator4.getMinP(), 0); + + Generator generator5 = getNetwork().getGenerator(GENERATOR_ID_5); + ActivePowerControl activePowerControl5 = generator5.getExtension(ActivePowerControl.class); + assertNotNull(activePowerControl5); + assertEquals(50, generator5.getMaxP(), 0); + assertEquals(2, activePowerControl5.getDroop(), 0); + + Generator generator6 = getNetwork().getGenerator(GENERATOR_ID_6); + ActivePowerControl activePowerControl6 = generator6.getExtension(ActivePowerControl.class); + assertNotNull(activePowerControl6); + assertEquals(50, generator6.getMaxP(), 0); + assertEquals(2, activePowerControl6.getDroop(), 0); + + Generator generator7 = getNetwork().getGenerator(GENERATOR_ID_7); + CoordinatedReactiveControl coordinatedReactiveControl7 = generator7.getExtension(CoordinatedReactiveControl.class); + assertNotNull(coordinatedReactiveControl7); + GeneratorStartup generatorStartup7 = generator7.getExtension(GeneratorStartup.class); + assertNotNull(generatorStartup7); + assertEquals(50, generatorStartup7.getMarginalCost(), 0); + assertEquals(0.25, coordinatedReactiveControl7.getQPercent(), 0); + + Generator generator8 = getNetwork().getGenerator(GENERATOR_ID_8); + CoordinatedReactiveControl coordinatedReactiveControl8 = generator8.getExtension(CoordinatedReactiveControl.class); + assertNotNull(coordinatedReactiveControl8); + GeneratorStartup generatorStartup8 = generator8.getExtension(GeneratorStartup.class); + assertNotNull(generatorStartup8); + assertEquals(60, generatorStartup8.getMarginalCost(), 0); + assertEquals(0.25, coordinatedReactiveControl8.getQPercent(), 0); + + assertEquals(2, getNetwork().getGenerator(GENERATOR_ID_9).getRatedS(), 0); + assertEquals(2, getNetwork().getGenerator(GENERATOR_ID_10).getRatedS(), 0); + } + + @Override + protected void assertAfterNetworkModificationDeletion() { + Generator generator1 = getNetwork().getGenerator(GENERATOR_ID_1); + GeneratorStartup generatorStartup1 = generator1.getExtension(GeneratorStartup.class); + assertNotNull(generatorStartup1); + assertEquals(100, generator1.getTargetP(), 0); + assertEquals(30, generatorStartup1.getMarginalCost(), 0); + assertEquals(25, generatorStartup1.getPlannedOutageRate(), 0); + assertEquals(55, generatorStartup1.getForcedOutageRate(), 0); + assertEquals(40, generatorStartup1.getPlannedActivePowerSetpoint(), 0); + assertEquals(500, generator1.getMaxP(), 0); + assertEquals(0, generator1.getMinP(), 0); + + Generator generator2 = getNetwork().getGenerator(GENERATOR_ID_2); + GeneratorStartup generatorStartup2 = generator2.getExtension(GeneratorStartup.class); + assertNotNull(generatorStartup2); + assertEquals(200, generator2.getTargetP(), 0); + assertEquals(30, generatorStartup2.getMarginalCost(), 0); + assertEquals(25, generatorStartup2.getPlannedOutageRate(), 0); + assertEquals(55, generatorStartup2.getForcedOutageRate(), 0); + assertEquals(40, generatorStartup2.getPlannedActivePowerSetpoint(), 0); + assertEquals(2000, generator2.getMaxP(), 0); + assertEquals(50, generator2.getMinP(), 0); + + Generator generator3 = getNetwork().getGenerator(GENERATOR_ID_3); + GeneratorShortCircuit generatorShortCircuit3 = generator3.getExtension(GeneratorShortCircuit.class); + assertNotNull(generatorShortCircuit3); + assertEquals(300, generator3.getTargetP(), 0); + assertEquals(40, generatorShortCircuit3.getDirectTransX(), 0); + assertEquals(38, generatorShortCircuit3.getStepUpTransformerX(), 0); + assertEquals(2000, generator3.getMaxP(), 0); + assertEquals(70, generator3.getMinP(), 0); + + Generator generator4 = getNetwork().getGenerator(GENERATOR_ID_4); + GeneratorShortCircuit generatorShortCircuit4 = generator4.getExtension(GeneratorShortCircuit.class); + assertNotNull(generatorShortCircuit4); + assertEquals(46, generatorShortCircuit4.getDirectTransX(), 0); + assertEquals(50, generatorShortCircuit4.getStepUpTransformerX(), 0); + assertEquals(400, generator4.getTargetP(), 0); + assertEquals(700, generator4.getMaxP(), 0); + assertEquals(110, generator4.getMinP(), 0); + + Generator generator5 = getNetwork().getGenerator(GENERATOR_ID_5); + ActivePowerControl activePowerControl5 = generator5.getExtension(ActivePowerControl.class); + assertNotNull(activePowerControl5); + assertEquals(2000, generator5.getMaxP(), 0); + assertEquals(2, activePowerControl5.getDroop(), 0); + + Generator generator6 = getNetwork().getGenerator(GENERATOR_ID_6); + ActivePowerControl activePowerControl6 = generator6.getExtension(ActivePowerControl.class); + assertNotNull(activePowerControl6); + assertEquals(500, generator6.getMaxP(), 0); + assertEquals(3, activePowerControl6.getDroop(), 0); + + Generator generator7 = getNetwork().getGenerator(GENERATOR_ID_7); + CoordinatedReactiveControl coordinatedReactiveControl7 = generator7.getExtension(CoordinatedReactiveControl.class); + assertNotNull(coordinatedReactiveControl7); + GeneratorStartup generatorStartup7 = generator7.getExtension(GeneratorStartup.class); + assertNotNull(generatorStartup7); + assertEquals(50, generatorStartup7.getMarginalCost(), 0); + assertEquals(6, coordinatedReactiveControl7.getQPercent(), 0); + + Generator generator8 = getNetwork().getGenerator(GENERATOR_ID_8); + CoordinatedReactiveControl coordinatedReactiveControl8 = generator8.getExtension(CoordinatedReactiveControl.class); + assertNotNull(coordinatedReactiveControl8); + GeneratorStartup generatorStartup8 = generator8.getExtension(GeneratorStartup.class); + assertNotNull(generatorStartup8); + assertEquals(60, generatorStartup8.getMarginalCost(), 0); + assertEquals(12, coordinatedReactiveControl8.getQPercent(), 0); + + assertEquals(60, getNetwork().getGenerator(GENERATOR_ID_9).getRatedS(), 0); + assertEquals(30, getNetwork().getGenerator(GENERATOR_ID_10).getRatedS(), 0); + } + + @Override + protected IdentifiableType getIdentifiableType() { + return IdentifiableType.GENERATOR; + } + + @Override + protected EquipmentType getEquipmentType() { + return EquipmentType.GENERATOR; + } +} diff --git a/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/LoadModificationByAssignmentTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/LoadModificationByAssignmentTest.java new file mode 100644 index 000000000..e4fb3de38 --- /dev/null +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/LoadModificationByAssignmentTest.java @@ -0,0 +1,134 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.modifications.byfilter.assignment; + +import com.powsybl.iidm.network.IdentifiableType; +import com.powsybl.iidm.network.LoadType; +import org.gridsuite.filter.AbstractFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; +import org.gridsuite.filter.utils.EquipmentType; +import org.gridsuite.modification.server.dto.byfilter.assignment.AssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.DoubleAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.EnumAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.LoadField; +import org.gridsuite.modification.server.impacts.AbstractBaseImpact; + +import java.util.Date; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.gridsuite.modification.server.Impacts.TestImpactUtils.createSubstationImpacts; +import static org.gridsuite.modification.server.utils.NetworkUtil.createLoad; +import static org.junit.Assert.assertEquals; + +/** + * @author Thang PHAM + */ +public class LoadModificationByAssignmentTest extends AbstractModificationByAssignmentTest { + private static final String LOAD_ID_1 = "load1"; + private static final String LOAD_ID_2 = "load2"; + private static final String LOAD_ID_3 = "load3"; + private static final String LOAD_ID_4 = "load4"; + + @Override + protected void createEquipments() { + createLoad(getNetwork().getVoltageLevel("v1"), LOAD_ID_1, "load1", 100, 100, 120, null, 5, null); + createLoad(getNetwork().getVoltageLevel("v2"), LOAD_ID_2, "load2", 200, 80, 90, null, 5, null); + createLoad(getNetwork().getVoltageLevel("v3"), LOAD_ID_3, "load3", 300, 100, 70, null, 5, null); + createLoad(getNetwork().getVoltageLevel("v4"), LOAD_ID_4, "load4", 400, 50, 150, null, 5, null); + } + + @Override + protected List getTestFilters() { + IdentifierListFilter filter1 = IdentifierListFilter.builder().id(FILTER_ID_1).modificationDate(new Date()).equipmentType(EquipmentType.LOAD) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(LOAD_ID_1, 1.0), + new IdentifierListFilterEquipmentAttributes(LOAD_ID_2, 2.0))) + .build(); + IdentifierListFilter filter2 = IdentifierListFilter.builder().id(FILTER_ID_2).modificationDate(new Date()).equipmentType(EquipmentType.LOAD) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(LOAD_ID_3, 2.0), + new IdentifierListFilterEquipmentAttributes(LOAD_ID_4, 5.0))) + .build(); + + return List.of(filter1, filter2); + } + + @Override + protected List> getAssignmentInfos() { + DoubleAssignmentInfos assignmentInfos1 = DoubleAssignmentInfos.builder() + .editedField(LoadField.ACTIVE_POWER.name()) + .value(25.) + .filters(List.of(filter1)) + .build(); + + DoubleAssignmentInfos assignmentInfos2 = DoubleAssignmentInfos.builder() + .editedField(LoadField.REACTIVE_POWER.name()) + .value(2.5) + .filters(List.of(filter2)) + .build(); + + EnumAssignmentInfos assignmentInfos3 = EnumAssignmentInfos.builder() + .editedField(LoadField.LOAD_TYPE.name()) + .value(LoadType.AUXILIARY.name()) + .filters(List.of(filter1)) + .build(); + + List> infosList = super.getAssignmentInfos(); + infosList.addAll(List.of(assignmentInfos1, assignmentInfos2, assignmentInfos3)); + + return infosList; + } + + @Override + protected List> getUpdatedAssignmentInfos() { + DoubleAssignmentInfos assignmentInfos1 = DoubleAssignmentInfos.builder() + .editedField(LoadField.ACTIVE_POWER.name()) + .value(200.) + .filters(List.of(filter1)) + .build(); + + return List.of(assignmentInfos1); + } + + @Override + protected void assertAfterNetworkModificationCreation() { + assertEquals(25, getNetwork().getLoad(LOAD_ID_1).getP0(), 0); + assertEquals(25, getNetwork().getLoad(LOAD_ID_2).getP0(), 0); + assertEquals(2.5, getNetwork().getLoad(LOAD_ID_3).getQ0(), 0); + assertEquals(2.5, getNetwork().getLoad(LOAD_ID_4).getQ0(), 0); + assertThat(getNetwork().getLoad(LOAD_ID_1).getLoadType()).isEqualTo(LoadType.AUXILIARY); + assertThat(getNetwork().getLoad(LOAD_ID_2).getLoadType()).isEqualTo(LoadType.AUXILIARY); + } + + @Override + protected void assertAfterNetworkModificationDeletion() { + assertEquals(100, getNetwork().getLoad(LOAD_ID_1).getP0(), 0); + assertEquals(80, getNetwork().getLoad(LOAD_ID_2).getP0(), 0); + assertEquals(70, getNetwork().getLoad(LOAD_ID_3).getQ0(), 0); + assertEquals(150, getNetwork().getLoad(LOAD_ID_4).getQ0(), 0); + } + + @Override + protected IdentifiableType getIdentifiableType() { + return IdentifiableType.LOAD; + } + + @Override + protected EquipmentType getEquipmentType() { + return EquipmentType.LOAD; + } + + @Override + protected void assertResultImpacts(List impacts) { + // NOTE: this assert is based on the return of NetworkStoreListener#reduceNetworkImpacts() + // since the test network has only 4 loads which is less than the collectionThreshold 5 + assertThat(impacts).containsAll(createSubstationImpacts(Set.of("s1", "s2"))); + } + +} diff --git a/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/ShuntCompensatorModificationByAssignmentTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/ShuntCompensatorModificationByAssignmentTest.java new file mode 100644 index 000000000..727b1d4b2 --- /dev/null +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/ShuntCompensatorModificationByAssignmentTest.java @@ -0,0 +1,184 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.modifications.byfilter.assignment; + +import com.powsybl.iidm.network.IdentifiableType; +import com.powsybl.iidm.network.ShuntCompensator; +import com.powsybl.iidm.network.ShuntCompensatorLinearModel; +import com.powsybl.iidm.network.extensions.ConnectablePosition; +import org.gridsuite.filter.AbstractFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; +import org.gridsuite.filter.utils.EquipmentType; +import org.gridsuite.modification.server.dto.byfilter.assignment.AssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.DoubleAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.IntegerAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.ShuntCompensatorField; +import org.junit.Test; + +import java.util.Date; +import java.util.List; + +import static org.gridsuite.modification.server.utils.NetworkUtil.createShuntCompensator; +import static org.junit.Assert.assertEquals; + +/** + * @author Thang PHAM + */ +public class ShuntCompensatorModificationByAssignmentTest extends AbstractModificationByAssignmentTest { + private static final String SHUNT_COMPENSATOR_ID_1 = "v1shunt"; + private static final String SHUNT_COMPENSATOR_ID_2 = "v2shunt"; + private static final String SHUNT_COMPENSATOR_ID_3 = "v3shunt"; + private static final String SHUNT_COMPENSATOR_ID_4 = "v4shunt"; + private static final String SHUNT_COMPENSATOR_ID_5 = "v5shunt"; + + @Test + public void testCreateWithWarning() throws Exception { + IdentifierListFilterEquipmentAttributes identifiableAttributes = getIdentifiableAttributes(SHUNT_COMPENSATOR_ID_1, 1.0); + IdentifierListFilterEquipmentAttributes wrongIdAttributes = getIdentifiableAttributes("wrongId", 1.0); + + IntegerAssignmentInfos assignmentInfos = IntegerAssignmentInfos.builder() + .editedField(ShuntCompensatorField.MAXIMUM_SECTION_COUNT.name()) + .value(2) + .filters(List.of(filterWithOneWrongId)) + .build(); + + checkCreateWithWarning(List.of(assignmentInfos), List.of(identifiableAttributes, wrongIdAttributes)); + assertEquals(2, getNetwork().getShuntCompensator(SHUNT_COMPENSATOR_ID_1).getMaximumSectionCount(), 0); + } + + @Override + protected void createEquipments() { + createShuntCompensator(getNetwork().getVoltageLevel("v1"), SHUNT_COMPENSATOR_ID_1, "v1shunt", 8, 225., 10, true, 4, 2, 3, 2, "cn11", 22, ConnectablePosition.Direction.BOTTOM); + createShuntCompensator(getNetwork().getVoltageLevel("v3"), SHUNT_COMPENSATOR_ID_3, "v3shunt", 10, 305., 20, true, 6, 3, 3, 4, "cn11", 22, ConnectablePosition.Direction.BOTTOM); + createShuntCompensator(getNetwork().getVoltageLevel("v4"), SHUNT_COMPENSATOR_ID_4, "v3shunt", 10, 305., 20, true, 15, 4, 3, 10, "cn11", 22, ConnectablePosition.Direction.BOTTOM); + } + + @Override + protected List getTestFilters() { + IdentifierListFilter filter1 = IdentifierListFilter.builder().id(FILTER_ID_1).modificationDate(new Date()).equipmentType(EquipmentType.SHUNT_COMPENSATOR) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(SHUNT_COMPENSATOR_ID_1, 1.0))) + .build(); + IdentifierListFilter filter2 = IdentifierListFilter.builder().id(FILTER_ID_2).modificationDate(new Date()).equipmentType(EquipmentType.SHUNT_COMPENSATOR) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(SHUNT_COMPENSATOR_ID_2, 1.0))) + .build(); + IdentifierListFilter filter3 = IdentifierListFilter.builder().id(FILTER_ID_3).modificationDate(new Date()).equipmentType(EquipmentType.SHUNT_COMPENSATOR) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(SHUNT_COMPENSATOR_ID_3, 1.0))) + .build(); + IdentifierListFilter filter4 = IdentifierListFilter.builder().id(FILTER_ID_4).modificationDate(new Date()).equipmentType(EquipmentType.SHUNT_COMPENSATOR) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(SHUNT_COMPENSATOR_ID_4, 1.0))) + .build(); + IdentifierListFilter filter5 = IdentifierListFilter.builder().id(FILTER_ID_5).modificationDate(new Date()).equipmentType(EquipmentType.SHUNT_COMPENSATOR) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(SHUNT_COMPENSATOR_ID_5, 1.0))) + .build(); + + return List.of(filter1, filter2, filter3, filter4, filter5); + } + + @Override + protected List> getAssignmentInfos() { + IntegerAssignmentInfos assignmentInfos1 = IntegerAssignmentInfos.builder() + .editedField(ShuntCompensatorField.MAXIMUM_SECTION_COUNT.name()) + .value(8) + .filters(List.of(filter1, filter2)) + .build(); + + IntegerAssignmentInfos assignmentInfos2 = IntegerAssignmentInfos.builder() + .editedField(ShuntCompensatorField.SECTION_COUNT.name()) + .value(2) + .filters(List.of(filter3)) + .build(); + + DoubleAssignmentInfos assignmentInfos3 = DoubleAssignmentInfos.builder() + .editedField(ShuntCompensatorField.MAXIMUM_SUSCEPTANCE.name()) + .value(5.) + .filters(List.of(filter4)) + .build(); + + DoubleAssignmentInfos assignmentInfos4 = DoubleAssignmentInfos.builder() + .editedField(ShuntCompensatorField.MAXIMUM_Q_AT_NOMINAL_VOLTAGE.name()) + .value(10.) + .filters(List.of(filter5)) + .build(); + + List> infosList = super.getAssignmentInfos(); + infosList.addAll(List.of(assignmentInfos1, assignmentInfos2, assignmentInfos3, assignmentInfos4)); + + return infosList; + } + + @Override + protected List> getUpdatedAssignmentInfos() { + IntegerAssignmentInfos assignmentInfos1 = IntegerAssignmentInfos.builder() + .editedField(ShuntCompensatorField.MAXIMUM_SECTION_COUNT.name()) + .value(150) + .filters(List.of(filter1, filter2)) + .build(); + + IntegerAssignmentInfos assignmentInfos2 = IntegerAssignmentInfos.builder() + .editedField(ShuntCompensatorField.SECTION_COUNT.name()) + .value(2) + .filters(List.of(filter3)) + .build(); + return List.of(assignmentInfos1, assignmentInfos2); + } + + @Override + protected void assertAfterNetworkModificationCreation() { + ShuntCompensator shuntCompensator1 = getNetwork().getShuntCompensator(SHUNT_COMPENSATOR_ID_1); + assertEquals(8, shuntCompensator1.getMaximumSectionCount()); + assertEquals(1, shuntCompensator1.getModel(ShuntCompensatorLinearModel.class).getBPerSection(), 0); + + ShuntCompensator shuntCompensator2 = getNetwork().getShuntCompensator(SHUNT_COMPENSATOR_ID_2); + assertEquals(8, shuntCompensator2.getMaximumSectionCount()); + assertEquals(0.375, shuntCompensator2.getModel(ShuntCompensatorLinearModel.class).getBPerSection(), 0); + + ShuntCompensator shuntCompensator3 = getNetwork().getShuntCompensator(SHUNT_COMPENSATOR_ID_3); + assertEquals(6, shuntCompensator3.getMaximumSectionCount()); + assertEquals(3, shuntCompensator3.getModel(ShuntCompensatorLinearModel.class).getBPerSection(), 0); + + ShuntCompensator shuntCompensator4 = getNetwork().getShuntCompensator(SHUNT_COMPENSATOR_ID_4); + assertEquals(10, shuntCompensator4.getSectionCount()); + + ShuntCompensator shuntCompensator5 = getNetwork().getShuntCompensator(SHUNT_COMPENSATOR_ID_5); + assertEquals(2, shuntCompensator5.getSectionCount()); + } + + @Override + protected void assertAfterNetworkModificationDeletion() { + ShuntCompensator shuntCompensator1 = getNetwork().getShuntCompensator(SHUNT_COMPENSATOR_ID_1); + assertEquals(4, shuntCompensator1.getMaximumSectionCount()); + assertEquals(2, shuntCompensator1.getModel(ShuntCompensatorLinearModel.class).getBPerSection(), 0); + + ShuntCompensator shuntCompensator2 = getNetwork().getShuntCompensator(SHUNT_COMPENSATOR_ID_2); + assertEquals(3, shuntCompensator2.getMaximumSectionCount()); + assertEquals(1, shuntCompensator2.getModel(ShuntCompensatorLinearModel.class).getBPerSection(), 0); + + ShuntCompensator shuntCompensator3 = getNetwork().getShuntCompensator(SHUNT_COMPENSATOR_ID_3); + assertEquals(6, shuntCompensator3.getMaximumSectionCount()); + assertEquals(3, shuntCompensator3.getModel(ShuntCompensatorLinearModel.class).getBPerSection(), 0); + + ShuntCompensator shuntCompensator4 = getNetwork().getShuntCompensator(SHUNT_COMPENSATOR_ID_4); + assertEquals(10, shuntCompensator4.getSectionCount()); + + ShuntCompensator shuntCompensator5 = getNetwork().getShuntCompensator(SHUNT_COMPENSATOR_ID_5); + assertEquals(2, shuntCompensator5.getSectionCount()); + assertEquals(1, shuntCompensator5.getModel(ShuntCompensatorLinearModel.class).getBPerSection(), 0); + } + + @Override + protected IdentifiableType getIdentifiableType() { + return IdentifiableType.SHUNT_COMPENSATOR; + } + + @Override + protected EquipmentType getEquipmentType() { + return EquipmentType.SHUNT_COMPENSATOR; + } + +} diff --git a/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/TwoWindingsTransformerModificationByAssignmentTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/TwoWindingsTransformerModificationByAssignmentTest.java new file mode 100644 index 000000000..0b1cb2f14 --- /dev/null +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/TwoWindingsTransformerModificationByAssignmentTest.java @@ -0,0 +1,576 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.modifications.byfilter.assignment; + +import com.github.tomakehurst.wiremock.client.WireMock; +import com.powsybl.iidm.network.*; +import com.powsybl.iidm.network.extensions.ConnectablePosition; +import org.gridsuite.filter.AbstractFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; +import org.gridsuite.filter.utils.EquipmentType; +import org.gridsuite.modification.server.dto.NetworkModificationResult; +import org.gridsuite.modification.server.dto.byfilter.assignment.AssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.DoubleAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.IntegerAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.TwoWindingsTransformerField; +import org.junit.Test; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import static org.gridsuite.modification.server.utils.NetworkUtil.createTwoWindingsTransformer; +import static org.junit.Assert.*; + +/** + * @author Thang PHAM + */ +public class TwoWindingsTransformerModificationByAssignmentTest extends AbstractModificationByAssignmentTest { + private static final String TWT_ID_1 = "twt1"; + private static final String TWT_ID_2 = "twt2"; + private static final String TWT_ID_3 = "twt3"; + private static final String TWT_ID_4 = "twt4"; + private static final String TWT_ID_5 = "twt5"; + private static final String TWT_ID_6 = "twt6"; + + @Test + public void testModifyTwtWithError() throws Exception { + // Test modifying ratio tab changer field when ratio tab changer is null + IdentifierListFilterEquipmentAttributes identifiableAttributes1 = getIdentifiableAttributes(TWT_ID_4, 1.); + IdentifierListFilterEquipmentAttributes identifiableAttributes2 = getIdentifiableAttributes(TWT_ID_6, 1.); + AbstractFilter filter = getFilterEquipments(FILTER_ID_4, List.of(identifiableAttributes1, identifiableAttributes2)); + DoubleAssignmentInfos assignmentInfos = DoubleAssignmentInfos.builder() + .editedField(TwoWindingsTransformerField.RATIO_TAP_POSITION.name()) + .value(1.) + .filters(List.of(filter4)) + .build(); + + checkCreateWithError(List.of(assignmentInfos), List.of(filter)); + + assertNull(getNetwork().getTwoWindingsTransformer(TWT_ID_4).getRatioTapChanger()); + assertNull(getNetwork().getTwoWindingsTransformer(TWT_ID_6).getRatioTapChanger()); + + // Test modifying phase tab changer field when phase tab changer is null + IdentifierListFilterEquipmentAttributes identifiableAttributes3 = getIdentifiableAttributes(TWT_ID_1, 1.); + IdentifierListFilterEquipmentAttributes identifiableAttributes4 = getIdentifiableAttributes(TWT_ID_2, 1.); + AbstractFilter filter2 = getFilterEquipments(FILTER_ID_1, List.of(identifiableAttributes3, identifiableAttributes4)); + DoubleAssignmentInfos assignmentInfos2 = DoubleAssignmentInfos.builder() + .editedField(TwoWindingsTransformerField.PHASE_TAP_POSITION.name()) + .value(1.) + .filters(List.of(filter1)) + .build(); + + checkCreateWithError(List.of(assignmentInfos2), List.of(filter2)); + + assertNull(getNetwork().getTwoWindingsTransformer(TWT_ID_1).getPhaseTapChanger()); + assertNull(getNetwork().getTwoWindingsTransformer(TWT_ID_2).getPhaseTapChanger()); + } + + @Test + public void testModifyTwtWithWarning() throws Exception { + IdentifierListFilterEquipmentAttributes identifiableAttributes1 = getIdentifiableAttributes(TWT_ID_1, 1.); + IdentifierListFilterEquipmentAttributes identifiableAttributes2 = getIdentifiableAttributes(TWT_ID_2, 1.); + IdentifierListFilterEquipmentAttributes identifiableAttributes3 = getIdentifiableAttributes(TWT_ID_4, 1.); + IdentifierListFilterEquipmentAttributes identifiableAttributes4 = getIdentifiableAttributes(TWT_ID_6, 1.); + AbstractFilter filterTwt1 = getFilterEquipments(FILTER_ID_1, List.of(identifiableAttributes1, identifiableAttributes2)); + AbstractFilter filterTwt2 = getFilterEquipments(FILTER_ID_4, List.of(identifiableAttributes3, identifiableAttributes4)); + + UUID stubId = wireMockServer.stubFor(WireMock.get(WireMock.urlMatching(getPath(true) + ".{2,}")) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(List.of(filterTwt1, filterTwt2))) + .withHeader("Content-Type", "application/json"))).getId(); + + IntegerAssignmentInfos assignmentInfos = IntegerAssignmentInfos.builder() + .filters(List.of(filter1, filter4)) + .editedField(TwoWindingsTransformerField.RATIO_TAP_POSITION.name()) + .value(4) + .build(); + + checkCreationApplicationStatus(List.of(assignmentInfos), NetworkModificationResult.ApplicationStatus.WITH_WARNINGS); + + assertNotNull(getNetwork().getTwoWindingsTransformer(TWT_ID_1).getRatioTapChanger()); + assertNotNull(getNetwork().getTwoWindingsTransformer(TWT_ID_2).getRatioTapChanger()); + assertEquals(4, getNetwork().getTwoWindingsTransformer(TWT_ID_1).getRatioTapChanger().getTapPosition()); + assertEquals(4, getNetwork().getTwoWindingsTransformer(TWT_ID_2).getRatioTapChanger().getTapPosition()); + assertNull(getNetwork().getTwoWindingsTransformer(TWT_ID_4).getRatioTapChanger()); + assertNull(getNetwork().getTwoWindingsTransformer(TWT_ID_6).getRatioTapChanger()); + + wireMockUtils.verifyGetRequest(stubId, PATH, handleQueryParams(List.of(FILTER_ID_1, FILTER_ID_4)), false); + } + + @Override + protected void createEquipments() { + Substation s1 = getNetwork().getSubstation("s1"); + Substation s3 = getNetwork().getSubstation("s3"); + TwoWindingsTransformer twt1 = createTwoWindingsTransformer(s1, TWT_ID_1, TWT_ID_1, 30, 40, 50, + 60, 10, 20, 100, 100, + "v1", "v2", + "trf1", 11, ConnectablePosition.Direction.TOP, + "trf1", 22, ConnectablePosition.Direction.BOTTOM); + twt1.setRatedS(11); + addRatioTapChangerSteps(twt1.newRatioTapChanger().setTargetV(50).setLowTapPosition(0).setTapPosition(1).setTargetDeadband(55)); + + TwoWindingsTransformer twt2 = createTwoWindingsTransformer(s1, TWT_ID_2, TWT_ID_2, 35, 45, 55, + 65, 15, 25, 101, 100, + "v1", "v4", + "trf1", 33, ConnectablePosition.Direction.TOP, + "trf1", 44, ConnectablePosition.Direction.BOTTOM); + twt2.setRatedS(10); + addRatioTapChangerSteps(twt2.newRatioTapChanger().setTargetV(53).setLowTapPosition(3).setTapPosition(4).setTargetDeadband(58)); + + TwoWindingsTransformer twt3 = createTwoWindingsTransformer(s1, TWT_ID_3, TWT_ID_3, 40, 50, 60, + 70, 20, 30, 101, 101, + "v2", "v4", + "trf1", 10, ConnectablePosition.Direction.TOP, + "trf1", 20, ConnectablePosition.Direction.BOTTOM); + twt3.setRatedS(25); + addRatioTapChangerSteps(twt3.newRatioTapChanger().setTargetV(56).setLowTapPosition(0).setTapPosition(1).setTargetDeadband(61)); + + TwoWindingsTransformer twt4 = createTwoWindingsTransformer(s3, TWT_ID_4, TWT_ID_4, 45, 55, 65, + 75, 25, 35, 100, 100, + "v5", "v6", + "trf1", 30, ConnectablePosition.Direction.TOP, + "trf1", 40, ConnectablePosition.Direction.BOTTOM); + twt4.setRatedS(15); + addPhaseTapChangerSteps(twt4.newPhaseTapChanger() + .setRegulationValue(45) + .setLowTapPosition(1) + .setTapPosition(2) + .setTargetDeadband(34) + .setRegulationMode(PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL)); + + TwoWindingsTransformer twt5 = createTwoWindingsTransformer(s3, TWT_ID_5, TWT_ID_5, 50, 60, 70, + 80, 30, 40, 101, 101, + "v5", "v6", + "trf1", 15, ConnectablePosition.Direction.TOP, + "trf1", 26, ConnectablePosition.Direction.BOTTOM); + twt5.setRatedS(30); + addPhaseTapChangerSteps(twt5.newPhaseTapChanger().setRegulationValue(46).setLowTapPosition(2).setTapPosition(2).setTargetDeadband(35)); + + TwoWindingsTransformer twt6 = createTwoWindingsTransformer(s3, TWT_ID_6, TWT_ID_6, 55, 65, 75, 85, + 35, 45, 102, 102, + "v5", "v6", + "trf1", 38, ConnectablePosition.Direction.TOP, + "trf1", 49, ConnectablePosition.Direction.BOTTOM); + twt6.setRatedS(20); + addPhaseTapChangerSteps(twt6.newPhaseTapChanger().setRegulationValue(47).setLowTapPosition(1).setTapPosition(1).setTargetDeadband(36)); + } + + @Override + protected List getTestFilters() { + IdentifierListFilter filter1 = IdentifierListFilter.builder().id(FILTER_ID_1).modificationDate(new Date()).equipmentType(EquipmentType.TWO_WINDINGS_TRANSFORMER) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(TWT_ID_1, 1.0), + new IdentifierListFilterEquipmentAttributes(TWT_ID_2, 2.0))) + .build(); + IdentifierListFilter filter2 = IdentifierListFilter.builder().id(FILTER_ID_2).modificationDate(new Date()).equipmentType(EquipmentType.TWO_WINDINGS_TRANSFORMER) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(TWT_ID_1, 1.0), + new IdentifierListFilterEquipmentAttributes(TWT_ID_3, 2.0))) + .build(); + IdentifierListFilter filter3 = IdentifierListFilter.builder().id(FILTER_ID_3).modificationDate(new Date()).equipmentType(EquipmentType.TWO_WINDINGS_TRANSFORMER) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(TWT_ID_4, 5.0), + new IdentifierListFilterEquipmentAttributes(TWT_ID_5, 6.0))) + .build(); + IdentifierListFilter filter4 = IdentifierListFilter.builder().id(FILTER_ID_4).modificationDate(new Date()).equipmentType(EquipmentType.TWO_WINDINGS_TRANSFORMER) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(TWT_ID_4, 5.0), + new IdentifierListFilterEquipmentAttributes(TWT_ID_6, 7.0))) + .build(); + + return List.of(filter1, filter2, filter3, filter4); + } + + @Override + protected List> getAssignmentInfos() { + DoubleAssignmentInfos assignmentInfos1 = DoubleAssignmentInfos.builder() + .filters(List.of(filter1)) + .editedField(TwoWindingsTransformerField.TARGET_V.name()) + .value(2.) + .build(); + + IntegerAssignmentInfos assignmentInfos2 = IntegerAssignmentInfos.builder() + .filters(List.of(filter2)) + .editedField(TwoWindingsTransformerField.RATIO_TAP_POSITION.name()) + .value(4) + .build(); + + IntegerAssignmentInfos assignmentInfos3 = IntegerAssignmentInfos.builder() + .filters(List.of(filter2)) + .editedField(TwoWindingsTransformerField.RATIO_LOW_TAP_POSITION.name()) + .value(4) + .build(); + + DoubleAssignmentInfos assignmentInfos4 = DoubleAssignmentInfos.builder() + .filters(List.of(filter1)) + .editedField(TwoWindingsTransformerField.RATIO_TARGET_DEADBAND.name()) + .value(5.) + .build(); + + DoubleAssignmentInfos assignmentInfos5 = DoubleAssignmentInfos.builder() + .filters(List.of(filter4)) + .editedField(TwoWindingsTransformerField.REGULATION_VALUE.name()) + .value(2.) + .build(); + + IntegerAssignmentInfos assignmentInfos6 = IntegerAssignmentInfos.builder() + .filters(List.of(filter3)) + .editedField(TwoWindingsTransformerField.PHASE_TAP_POSITION.name()) + .value(2) + .build(); + + IntegerAssignmentInfos assignmentInfos7 = IntegerAssignmentInfos.builder() + .filters(List.of(filter3)) + .editedField(TwoWindingsTransformerField.PHASE_LOW_TAP_POSITION.name()) + .value(2) + .build(); + + DoubleAssignmentInfos assignmentInfos8 = DoubleAssignmentInfos.builder() + .filters(List.of(filter4)) + .editedField(TwoWindingsTransformerField.PHASE_TARGET_DEADBAND.name()) + .value(10.) + .build(); + + DoubleAssignmentInfos assignmentInfos9 = DoubleAssignmentInfos.builder() + .filters(List.of(filter1, filter4)) + .editedField(TwoWindingsTransformerField.X.name()) + .value(20.) + .build(); + + DoubleAssignmentInfos assignmentInfos10 = DoubleAssignmentInfos.builder() + .filters(List.of(filter2, filter3)) + .editedField(TwoWindingsTransformerField.R.name()) + .value(2.) + .build(); + + DoubleAssignmentInfos assignmentInfos11 = DoubleAssignmentInfos.builder() + .filters(List.of(filter4, filter2)) + .editedField(TwoWindingsTransformerField.G.name()) + .value(25.) + .build(); + + DoubleAssignmentInfos assignmentInfos12 = DoubleAssignmentInfos.builder() + .filters(List.of(filter1, filter3)) + .editedField(TwoWindingsTransformerField.B.name()) + .value(2.5) + .build(); + + DoubleAssignmentInfos assignmentInfos13 = DoubleAssignmentInfos.builder() + .filters(List.of(filter2)) + .editedField(TwoWindingsTransformerField.RATED_U1.name()) + .value(15.) + .build(); + + DoubleAssignmentInfos assignmentInfos14 = DoubleAssignmentInfos.builder() + .filters(List.of(filter3, filter2)) + .editedField(TwoWindingsTransformerField.RATED_U2.name()) + .value(0.5) + .build(); + + DoubleAssignmentInfos assignmentInfos15 = DoubleAssignmentInfos.builder() + .filters(List.of(filter1, filter2)) + .editedField(TwoWindingsTransformerField.RATED_S.name()) + .value(2.) + .build(); + List> infosList = super.getAssignmentInfos(); + infosList.addAll(List.of(assignmentInfos1, + assignmentInfos2, + assignmentInfos3, + assignmentInfos4, + assignmentInfos5, + assignmentInfos6, + assignmentInfos7, + assignmentInfos8, + assignmentInfos9, + assignmentInfos10, + assignmentInfos11, + assignmentInfos12, + assignmentInfos13, + assignmentInfos14, + assignmentInfos15)); + + return infosList; + } + + @Override + protected List> getUpdatedAssignmentInfos() { + DoubleAssignmentInfos assignmentInfos1 = DoubleAssignmentInfos.builder() + .filters(List.of(filter3)) + .editedField(TwoWindingsTransformerField.TARGET_V.name()) + .value(2.) + .build(); + + IntegerAssignmentInfos assignmentInfos2 = IntegerAssignmentInfos.builder() + .filters(List.of(filter2)) + .editedField(TwoWindingsTransformerField.RATIO_TAP_POSITION.name()) + .value(3) + .build(); + + IntegerAssignmentInfos assignmentInfos3 = IntegerAssignmentInfos.builder() + .filters(List.of(filter1)) + .editedField(TwoWindingsTransformerField.RATIO_LOW_TAP_POSITION.name()) + .value(3) + .build(); + + return List.of(assignmentInfos1, + assignmentInfos2, + assignmentInfos3); + } + + @Override + protected IdentifiableType getIdentifiableType() { + return IdentifiableType.TWO_WINDINGS_TRANSFORMER; + } + + @Override + protected EquipmentType getEquipmentType() { + return EquipmentType.TWO_WINDINGS_TRANSFORMER; + } + + @Override + protected void assertAfterNetworkModificationCreation() { + TwoWindingsTransformer twt1 = getNetwork().getTwoWindingsTransformer(TWT_ID_1); + RatioTapChanger ratioTapChanger1 = twt1.getRatioTapChanger(); + assertNotNull(ratioTapChanger1); + assertEquals(2, ratioTapChanger1.getTargetV(), 0); + assertEquals(4, ratioTapChanger1.getLowTapPosition()); + assertEquals(4, ratioTapChanger1.getTapPosition()); + assertEquals(5, ratioTapChanger1.getTargetDeadband(), 0); + assertEquals(20, twt1.getX(), 0); + assertEquals(2.5, twt1.getB(), 0); + assertEquals(2, twt1.getR(), 0); + assertEquals(25, twt1.getG(), 0); + assertEquals(15, twt1.getRatedU1(), 0); + assertEquals(0.5, twt1.getRatedU2(), 0); + assertEquals(2, twt1.getRatedS(), 0); + + TwoWindingsTransformer twt2 = getNetwork().getTwoWindingsTransformer(TWT_ID_2); + RatioTapChanger ratioTapChanger2 = twt2.getRatioTapChanger(); + assertNotNull(ratioTapChanger2); + assertEquals(2, ratioTapChanger2.getTargetV(), 0); + assertEquals(3, ratioTapChanger2.getLowTapPosition()); + assertEquals(4, ratioTapChanger2.getTapPosition()); + assertEquals(5, ratioTapChanger2.getTargetDeadband(), 0); + assertEquals(20, twt2.getX(), 0); + assertEquals(2.5, twt2.getB(), 0); + assertEquals(15, twt2.getRatedU1(), 0); + assertEquals(2, twt2.getRatedS(), 0); + + TwoWindingsTransformer twt3 = getNetwork().getTwoWindingsTransformer(TWT_ID_3); + RatioTapChanger ratioTapChanger3 = twt3.getRatioTapChanger(); + assertNotNull(ratioTapChanger3); + assertEquals(4, ratioTapChanger3.getLowTapPosition()); + assertEquals(4, ratioTapChanger3.getTapPosition()); + assertEquals(2, twt3.getR(), 0); + assertEquals(25, twt3.getG(), 0); + assertEquals(15, twt3.getRatedU1(), 0); + assertEquals(0.5, twt3.getRatedU2(), 0); + assertEquals(2, twt3.getRatedS(), 0); + + TwoWindingsTransformer twt4 = getNetwork().getTwoWindingsTransformer(TWT_ID_4); + PhaseTapChanger phaseTapChanger4 = twt4.getPhaseTapChanger(); + assertNotNull(phaseTapChanger4); + assertEquals(2, phaseTapChanger4.getRegulationValue(), 0); + assertEquals(2, phaseTapChanger4.getLowTapPosition()); + assertEquals(2, phaseTapChanger4.getTapPosition()); + assertEquals(10, phaseTapChanger4.getTargetDeadband(), 0); + assertEquals(2, twt4.getR(), 0); + assertEquals(20, twt4.getX(), 0); + assertEquals(25, twt4.getG(), 0); + assertEquals(2.5, twt4.getB(), 0); + assertEquals(25, twt4.getRatedU1(), 0); + assertEquals(0.5, twt4.getRatedU2(), 0); + assertEquals(15, twt4.getRatedS(), 0); + + TwoWindingsTransformer twt5 = getNetwork().getTwoWindingsTransformer(TWT_ID_5); + PhaseTapChanger phaseTapChanger5 = twt5.getPhaseTapChanger(); + assertNotNull(phaseTapChanger4); + assertEquals(2, phaseTapChanger5.getLowTapPosition()); + assertEquals(2, phaseTapChanger5.getTapPosition()); + assertEquals(2, twt5.getR(), 0); + assertEquals(2.5, twt5.getB(), 0); + assertEquals(0.5, twt5.getRatedU2(), 0); + + TwoWindingsTransformer twt6 = getNetwork().getTwoWindingsTransformer(TWT_ID_6); + PhaseTapChanger phaseTapChanger6 = twt6.getPhaseTapChanger(); + assertNotNull(phaseTapChanger4); + assertEquals(2, phaseTapChanger6.getRegulationValue(), 0); + assertEquals(10, phaseTapChanger6.getTargetDeadband(), 0); + assertEquals(20, twt6.getX(), 0); + assertEquals(25, twt6.getG(), 0); + } + + @Override + protected void assertAfterNetworkModificationDeletion() { + TwoWindingsTransformer twt1 = getNetwork().getTwoWindingsTransformer(TWT_ID_1); + RatioTapChanger ratioTapChanger1 = twt1.getRatioTapChanger(); + assertNotNull(ratioTapChanger1); + assertEquals(50, ratioTapChanger1.getTargetV(), 0); + assertEquals(0, ratioTapChanger1.getLowTapPosition()); + assertEquals(1, ratioTapChanger1.getTapPosition()); + assertEquals(55, ratioTapChanger1.getTargetDeadband(), 0); + assertEquals(40, twt1.getX(), 0); + assertEquals(60, twt1.getB(), 0); + assertEquals(30, twt1.getR(), 0); + assertEquals(50, twt1.getG(), 0); + assertEquals(10, twt1.getRatedU1(), 0); + assertEquals(20, twt1.getRatedU2(), 0); + assertEquals(11, twt1.getRatedS(), 0); + + TwoWindingsTransformer twt2 = getNetwork().getTwoWindingsTransformer(TWT_ID_2); + RatioTapChanger ratioTapChanger2 = twt2.getRatioTapChanger(); + assertNotNull(ratioTapChanger2); + assertEquals(53, ratioTapChanger2.getTargetV(), 0); + assertEquals(3, ratioTapChanger2.getLowTapPosition()); + assertEquals(4, ratioTapChanger2.getTapPosition()); + assertEquals(58, ratioTapChanger2.getTargetDeadband(), 0); + assertEquals(45, twt2.getX(), 0); + assertEquals(65, twt2.getB(), 0); + assertEquals(15, twt2.getRatedU1(), 0); + assertEquals(10, twt2.getRatedS(), 0); + + TwoWindingsTransformer twt3 = getNetwork().getTwoWindingsTransformer(TWT_ID_3); + RatioTapChanger ratioTapChanger3 = twt3.getRatioTapChanger(); + assertNotNull(ratioTapChanger3); + assertEquals(0, ratioTapChanger3.getLowTapPosition()); + assertEquals(1, ratioTapChanger3.getTapPosition()); + assertEquals(40, twt3.getR(), 0); + assertEquals(60, twt3.getG(), 0); + assertEquals(20, twt3.getRatedU1(), 0); + assertEquals(30, twt3.getRatedU2(), 0); + assertEquals(25, twt3.getRatedS(), 0); + + TwoWindingsTransformer twt4 = getNetwork().getTwoWindingsTransformer(TWT_ID_4); + PhaseTapChanger phaseTapChanger4 = twt4.getPhaseTapChanger(); + assertNotNull(phaseTapChanger4); + assertEquals(45, phaseTapChanger4.getRegulationValue(), 0); + assertEquals(1, phaseTapChanger4.getLowTapPosition()); + assertEquals(2, phaseTapChanger4.getTapPosition()); + assertEquals(34, phaseTapChanger4.getTargetDeadband(), 0); + assertEquals(45, twt4.getR(), 0); + assertEquals(55, twt4.getX(), 0); + assertEquals(65, twt4.getG(), 0); + assertEquals(75, twt4.getB(), 0); + assertEquals(25, twt4.getRatedU1(), 0); + assertEquals(35, twt4.getRatedU2(), 0); + assertEquals(15, twt4.getRatedS(), 0); + + TwoWindingsTransformer twt5 = getNetwork().getTwoWindingsTransformer(TWT_ID_5); + PhaseTapChanger phaseTapChanger5 = twt5.getPhaseTapChanger(); + assertNotNull(phaseTapChanger4); + assertEquals(2, phaseTapChanger5.getLowTapPosition()); + assertEquals(2, phaseTapChanger5.getTapPosition()); + assertEquals(50, twt5.getR(), 0); + assertEquals(80, twt5.getB(), 0); + assertEquals(40, twt5.getRatedU2(), 0); + + TwoWindingsTransformer twt6 = getNetwork().getTwoWindingsTransformer(TWT_ID_6); + PhaseTapChanger phaseTapChanger6 = twt6.getPhaseTapChanger(); + assertNotNull(phaseTapChanger4); + assertEquals(47, phaseTapChanger6.getRegulationValue(), 0); + assertEquals(36, phaseTapChanger6.getTargetDeadband(), 0); + assertEquals(65, twt6.getX(), 0); + assertEquals(75, twt6.getG(), 0); + } + + private void addRatioTapChangerSteps(RatioTapChangerAdder ratioTapChangerAdder) { + ratioTapChangerAdder.beginStep() + .setR(39.78473) + .setX(39.784725) + .setG(0.0) + .setB(0.0) + .setRho(15.0) + .endStep() + .beginStep() + .setR(39.78474) + .setX(39.784726) + .setG(0.0) + .setB(0.0) + .setRho(15.0) + .endStep() + .beginStep() + .setR(39.78473) + .setX(39.784725) + .setG(0.0) + .setB(0.0) + .setRho(15.0) + .endStep() + .beginStep() + .setR(39.78474) + .setX(39.784726) + .setG(0.0) + .setB(0.0) + .setRho(15.0) + .endStep() + .beginStep() + .setR(39.78473) + .setX(39.784725) + .setG(0.0) + .setB(0.0) + .setRho(5.0) + .endStep() + .beginStep() + .setR(39.78474) + .setX(39.784726) + .setG(0.0) + .setB(0.0) + .setRho(15.0) + .endStep() + .add(); + } + + private void addPhaseTapChangerSteps(PhaseTapChangerAdder phaseTapChangerAdder) { + phaseTapChangerAdder.beginStep() + .setR(39.78473) + .setX(39.784725) + .setG(0.0) + .setB(0.0) + .setRho(15.0) + .setAlpha(1.) + .endStep() + .beginStep() + .setR(39.78475) + .setX(39.784727) + .setG(0.0) + .setB(0.0) + .setRho(15.0) + .setAlpha(1.1) + .endStep() + .beginStep() + .setR(39.78473) + .setX(39.784725) + .setG(0.0) + .setB(0.0) + .setRho(15.0) + .setAlpha(1.) + .endStep() + .beginStep() + .setR(39.78475) + .setX(39.784727) + .setG(0.0) + .setB(0.0) + .setRho(15.0) + .setAlpha(1.1) + .endStep() + .beginStep() + .setR(39.78473) + .setX(39.784725) + .setG(0.0) + .setB(0.0) + .setRho(15.0) + .setAlpha(1.) + .endStep() + .beginStep() + .setR(39.78475) + .setX(39.784727) + .setG(0.0) + .setB(0.0) + .setRho(15.0) + .setAlpha(1.1) + .endStep() + .add(); + } +} diff --git a/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/VoltageLevelModificationByAssignmentTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/VoltageLevelModificationByAssignmentTest.java new file mode 100644 index 000000000..4e105be3c --- /dev/null +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/assignment/VoltageLevelModificationByAssignmentTest.java @@ -0,0 +1,225 @@ +/** + * Copyright (c) 2024, 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/. + */ + +package org.gridsuite.modification.server.modifications.byfilter.assignment; + +import com.powsybl.iidm.network.IdentifiableType; +import com.powsybl.iidm.network.VoltageLevel; +import com.powsybl.iidm.network.extensions.IdentifiableShortCircuit; +import com.powsybl.iidm.network.extensions.IdentifiableShortCircuitAdder; +import org.gridsuite.filter.AbstractFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; +import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; +import org.gridsuite.filter.utils.EquipmentType; +import org.gridsuite.modification.server.dto.byfilter.assignment.AssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.assignment.DoubleAssignmentInfos; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.VoltageLevelField; + +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author Thang PHAM + */ +public class VoltageLevelModificationByAssignmentTest extends AbstractModificationByAssignmentTest { + private static final String VOLTAGE_LEVEL_ID_1 = "v1"; + private static final String VOLTAGE_LEVEL_ID_2 = "v2"; + private static final String VOLTAGE_LEVEL_ID_3 = "v3"; + private static final String VOLTAGE_LEVEL_ID_4 = "v4"; + private static final String VOLTAGE_LEVEL_ID_5 = "v5"; + private static final String VOLTAGE_LEVEL_ID_6 = "v6"; + + @Override + protected void createEquipments() { + getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_1).setNominalV(400) + .setHighVoltageLimit(200) + .setLowVoltageLimit(100) + .newExtension(IdentifiableShortCircuitAdder.class).withIpMin(10).withIpMax(120).add(); + + getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_2).setNominalV(150) + .setLowVoltageLimit(100) + .setHighVoltageLimit(1000) + .newExtension(IdentifiableShortCircuitAdder.class).withIpMin(10).withIpMax(120).add(); + + getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_3).setNominalV(70) + .setLowVoltageLimit(50) + .setHighVoltageLimit(250) + .newExtension(IdentifiableShortCircuitAdder.class).withIpMin(50).withIpMax(150).add(); + + getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_4).setNominalV(100) + .setLowVoltageLimit(70) + .setHighVoltageLimit(300) + .newExtension(IdentifiableShortCircuitAdder.class).withIpMin(10).withIpMax(100).add(); + + getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_5).setNominalV(210) + .setLowVoltageLimit(10) + .setHighVoltageLimit(500) + .newExtension(IdentifiableShortCircuitAdder.class).withIpMin(25).withIpMax(75).add(); + + getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_6).setNominalV(750) + .setHighVoltageLimit(1000) + .setLowVoltageLimit(90) + .newExtension(IdentifiableShortCircuitAdder.class).withIpMin(100).withIpMax(200).add(); + } + + @Override + protected List getTestFilters() { + IdentifierListFilter filter1 = IdentifierListFilter.builder().id(FILTER_ID_1).modificationDate(new Date()).equipmentType(EquipmentType.VOLTAGE_LEVEL) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(VOLTAGE_LEVEL_ID_1, 1.0), + new IdentifierListFilterEquipmentAttributes(VOLTAGE_LEVEL_ID_2, 2.0))) + .build(); + IdentifierListFilter filter2 = IdentifierListFilter.builder().id(FILTER_ID_2).modificationDate(new Date()).equipmentType(EquipmentType.VOLTAGE_LEVEL) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(VOLTAGE_LEVEL_ID_3, 2.0), + new IdentifierListFilterEquipmentAttributes(VOLTAGE_LEVEL_ID_4, 5.0))) + .build(); + IdentifierListFilter filter3 = IdentifierListFilter.builder().id(FILTER_ID_3).modificationDate(new Date()).equipmentType(EquipmentType.VOLTAGE_LEVEL) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(VOLTAGE_LEVEL_ID_5, 6.0), + new IdentifierListFilterEquipmentAttributes(VOLTAGE_LEVEL_ID_6, 7.0))) + .build(); + IdentifierListFilter filter4 = IdentifierListFilter.builder().id(FILTER_ID_4).modificationDate(new Date()).equipmentType(EquipmentType.VOLTAGE_LEVEL) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(VOLTAGE_LEVEL_ID_2, 2.0), + new IdentifierListFilterEquipmentAttributes(VOLTAGE_LEVEL_ID_5, 6.0))) + .build(); + IdentifierListFilter filter5 = IdentifierListFilter.builder().id(FILTER_ID_5).modificationDate(new Date()).equipmentType(EquipmentType.VOLTAGE_LEVEL) + .filterEquipmentsAttributes(List.of(new IdentifierListFilterEquipmentAttributes(VOLTAGE_LEVEL_ID_4, 5.0), + new IdentifierListFilterEquipmentAttributes(VOLTAGE_LEVEL_ID_6, 7.0))) + .build(); + + return List.of(filter1, filter2, filter3, filter4, filter5); + } + + @Override + protected List> getAssignmentInfos() { + DoubleAssignmentInfos assignmentInfos1 = DoubleAssignmentInfos.builder() + .editedField(VoltageLevelField.LOW_VOLTAGE_LIMIT.name()) + .value(10.) + .filters(List.of(filter1, filter2)) + .build(); + + DoubleAssignmentInfos assignmentInfos2 = DoubleAssignmentInfos.builder() + .editedField(VoltageLevelField.HIGH_VOLTAGE_LIMIT.name()) + .value(120.) + .filters(List.of(filter3)) + .build(); + + DoubleAssignmentInfos assignmentInfos3 = DoubleAssignmentInfos.builder() + .editedField(VoltageLevelField.NOMINAL_VOLTAGE.name()) + .value(150.) + .filters(List.of(filter4)) + .build(); + + DoubleAssignmentInfos assignmentInfos4 = DoubleAssignmentInfos.builder() + .editedField(VoltageLevelField.LOW_SHORT_CIRCUIT_CURRENT_LIMIT.name()) + .value(2.) + .filters(List.of(filter5)) + .build(); + + DoubleAssignmentInfos assignmentInfos5 = DoubleAssignmentInfos.builder() + .editedField(VoltageLevelField.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT.name()) + .value(5.) + .filters(List.of(filter4, filter5)) + .build(); + + return List.of(assignmentInfos1, assignmentInfos2, assignmentInfos3, assignmentInfos4, assignmentInfos5); + } + + @Override + protected List> getUpdatedAssignmentInfos() { + DoubleAssignmentInfos assignmentInfos1 = DoubleAssignmentInfos.builder() + .editedField(VoltageLevelField.LOW_VOLTAGE_LIMIT.name()) + .value(5.) + .filters(List.of(filter1, filter2)) + .build(); + + DoubleAssignmentInfos assignmentInfos2 = DoubleAssignmentInfos.builder() + .editedField(VoltageLevelField.HIGH_VOLTAGE_LIMIT.name()) + .value(1.5) + .filters(List.of(filter3)) + .build(); + + DoubleAssignmentInfos assignmentInfos3 = DoubleAssignmentInfos.builder() + .editedField(VoltageLevelField.NOMINAL_VOLTAGE.name()) + .value(150.) + .filters(List.of(filter4)) + .build(); + + List> infosList = super.getAssignmentInfos(); + infosList.addAll(List.of(assignmentInfos1, assignmentInfos2, assignmentInfos3)); + + return infosList; + } + + @Override + protected IdentifiableType getIdentifiableType() { + return IdentifiableType.VOLTAGE_LEVEL; + } + + @Override + protected EquipmentType getEquipmentType() { + return EquipmentType.VOLTAGE_LEVEL; + } + + @Override + protected void assertAfterNetworkModificationCreation() { + assertEquals(10, getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_1).getLowVoltageLimit(), 0); + assertEquals(10, getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_2).getLowVoltageLimit(), 0); + assertEquals(10, getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_3).getLowVoltageLimit(), 0); + + VoltageLevel voltageLevel4 = getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_4); + IdentifiableShortCircuit identifiableShortCircuit4 = voltageLevel4.getExtension(IdentifiableShortCircuit.class); + assertNotNull(identifiableShortCircuit4); + assertEquals(10, voltageLevel4.getLowVoltageLimit(), 0); + assertEquals(2, identifiableShortCircuit4.getIpMin(), 0); + assertEquals(5, identifiableShortCircuit4.getIpMax(), 0); + + VoltageLevel voltageLevel5 = getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_5); + IdentifiableShortCircuit identifiableShortCircuit5 = voltageLevel5.getExtension(IdentifiableShortCircuit.class); + assertNotNull(identifiableShortCircuit5); + assertEquals(120, voltageLevel5.getHighVoltageLimit(), 0); + assertEquals(150, voltageLevel5.getNominalV(), 0); + assertEquals(5, identifiableShortCircuit5.getIpMax(), 0); + + VoltageLevel voltageLevel6 = getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_6); + IdentifiableShortCircuit identifiableShortCircuit6 = voltageLevel6.getExtension(IdentifiableShortCircuit.class); + assertNotNull(identifiableShortCircuit6); + assertEquals(120, voltageLevel6.getHighVoltageLimit(), 0); + assertEquals(2, identifiableShortCircuit6.getIpMin(), 0); + assertEquals(5, identifiableShortCircuit6.getIpMax(), 0); + } + + @Override + protected void assertAfterNetworkModificationDeletion() { + assertEquals(100, getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_1).getLowVoltageLimit(), 0); + assertEquals(100, getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_2).getLowVoltageLimit(), 0); + assertEquals(250, getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_3).getHighVoltageLimit(), 0); + + VoltageLevel voltageLevel4 = getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_4); + IdentifiableShortCircuit identifiableShortCircuit4 = voltageLevel4.getExtension(IdentifiableShortCircuit.class); + assertNotNull(identifiableShortCircuit4); + assertEquals(300, voltageLevel4.getHighVoltageLimit(), 0); + assertEquals(10, identifiableShortCircuit4.getIpMin(), 0); + assertEquals(100, identifiableShortCircuit4.getIpMax(), 0); + + VoltageLevel voltageLevel5 = getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_5); + IdentifiableShortCircuit identifiableShortCircuit5 = voltageLevel5.getExtension(IdentifiableShortCircuit.class); + assertNotNull(identifiableShortCircuit5); + assertEquals(500, voltageLevel5.getHighVoltageLimit(), 0); + assertEquals(210, voltageLevel5.getNominalV(), 0); + assertEquals(75, identifiableShortCircuit5.getIpMax(), 0); + + VoltageLevel voltageLevel6 = getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_6); + IdentifiableShortCircuit identifiableShortCircuit6 = voltageLevel6.getExtension(IdentifiableShortCircuit.class); + assertNotNull(identifiableShortCircuit6); + assertEquals(1000, voltageLevel6.getHighVoltageLimit(), 0); + assertEquals(100, identifiableShortCircuit6.getIpMin(), 0); + assertEquals(200, identifiableShortCircuit6.getIpMax(), 0); + } + +} diff --git a/src/test/java/org/gridsuite/modification/server/modifications/AbstractByFormulaModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/AbstractByFormulaModificationTest.java similarity index 96% rename from src/test/java/org/gridsuite/modification/server/modifications/AbstractByFormulaModificationTest.java rename to src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/AbstractByFormulaModificationTest.java index 650e80d9a..355ed6f17 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/AbstractByFormulaModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/AbstractByFormulaModificationTest.java @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.modifications; +package org.gridsuite.modification.server.modifications.byfilter.formula; import com.fasterxml.jackson.core.type.TypeReference; import com.github.tomakehurst.wiremock.client.WireMock; @@ -19,10 +19,11 @@ import org.gridsuite.modification.server.dto.ByFormulaModificationInfos; import org.gridsuite.modification.server.dto.FilterInfos; import org.gridsuite.modification.server.dto.NetworkModificationResult; -import org.gridsuite.modification.server.dto.formula.FormulaInfos; -import org.gridsuite.modification.server.dto.formula.Operator; -import org.gridsuite.modification.server.dto.formula.ReferenceFieldOrValue; +import org.gridsuite.modification.server.dto.byfilter.formula.FormulaInfos; +import org.gridsuite.modification.server.dto.byfilter.formula.Operator; +import org.gridsuite.modification.server.dto.byfilter.formula.ReferenceFieldOrValue; import org.gridsuite.modification.server.impacts.AbstractBaseImpact; +import org.gridsuite.modification.server.modifications.AbstractNetworkModificationTest; import org.gridsuite.modification.server.service.FilterService; import org.gridsuite.modification.server.utils.NetworkCreation; import org.junit.Before; @@ -264,8 +265,8 @@ Map handleQueryParams(List filterIds) { return Map.of("ids", WireMock.matching(filterIds.stream().map(uuid -> ".+").collect(Collectors.joining(",")))); } - String getPath(boolean isRegexPhat) { - if (isRegexPhat) { + String getPath(boolean isRegexPath) { + if (isRegexPath) { return "/v1/filters/metadata\\?ids="; } return "/v1/filters/metadata?ids="; diff --git a/src/test/java/org/gridsuite/modification/server/modifications/BatteryByFormulaModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/BatteryByFormulaModificationTest.java similarity index 96% rename from src/test/java/org/gridsuite/modification/server/modifications/BatteryByFormulaModificationTest.java rename to src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/BatteryByFormulaModificationTest.java index c6f9d91f0..34eb4f325 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/BatteryByFormulaModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/BatteryByFormulaModificationTest.java @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.modifications; +package org.gridsuite.modification.server.modifications.byfilter.formula; import com.powsybl.iidm.network.IdentifiableType; import com.powsybl.iidm.network.extensions.ActivePowerControl; @@ -14,10 +14,10 @@ import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; import org.gridsuite.filter.utils.EquipmentType; -import org.gridsuite.modification.server.dto.formula.FormulaInfos; -import org.gridsuite.modification.server.dto.formula.Operator; -import org.gridsuite.modification.server.dto.formula.ReferenceFieldOrValue; -import org.gridsuite.modification.server.dto.formula.equipmentfield.BatteryField; +import org.gridsuite.modification.server.dto.byfilter.formula.FormulaInfos; +import org.gridsuite.modification.server.dto.byfilter.formula.Operator; +import org.gridsuite.modification.server.dto.byfilter.formula.ReferenceFieldOrValue; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.BatteryField; import org.junit.Test; import java.util.Date; diff --git a/src/test/java/org/gridsuite/modification/server/modifications/GeneratorByFormulaModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/GeneratorByFormulaModificationTest.java similarity index 98% rename from src/test/java/org/gridsuite/modification/server/modifications/GeneratorByFormulaModificationTest.java rename to src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/GeneratorByFormulaModificationTest.java index ae5b98b1b..d841030bc 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/GeneratorByFormulaModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/GeneratorByFormulaModificationTest.java @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.modifications; +package org.gridsuite.modification.server.modifications.byfilter.formula; import com.powsybl.iidm.network.Generator; import com.powsybl.iidm.network.IdentifiableType; @@ -23,10 +23,10 @@ import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; import org.gridsuite.filter.utils.EquipmentType; import org.gridsuite.modification.server.dto.FilterInfos; -import org.gridsuite.modification.server.dto.formula.FormulaInfos; -import org.gridsuite.modification.server.dto.formula.Operator; -import org.gridsuite.modification.server.dto.formula.ReferenceFieldOrValue; -import org.gridsuite.modification.server.dto.formula.equipmentfield.GeneratorField; +import org.gridsuite.modification.server.dto.byfilter.formula.FormulaInfos; +import org.gridsuite.modification.server.dto.byfilter.formula.Operator; +import org.gridsuite.modification.server.dto.byfilter.formula.ReferenceFieldOrValue; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.GeneratorField; import org.junit.Test; import org.junit.jupiter.api.Tag; diff --git a/src/test/java/org/gridsuite/modification/server/modifications/LoadByFormulaModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/LoadByFormulaModificationTest.java similarity index 85% rename from src/test/java/org/gridsuite/modification/server/modifications/LoadByFormulaModificationTest.java rename to src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/LoadByFormulaModificationTest.java index e765bf8eb..47e333d41 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/LoadByFormulaModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/LoadByFormulaModificationTest.java @@ -5,22 +5,25 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.modifications; +package org.gridsuite.modification.server.modifications.byfilter.formula; import com.powsybl.iidm.network.IdentifiableType; import org.gridsuite.filter.AbstractFilter; import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; import org.gridsuite.filter.utils.EquipmentType; -import org.gridsuite.modification.server.dto.formula.FormulaInfos; -import org.gridsuite.modification.server.dto.formula.Operator; -import org.gridsuite.modification.server.dto.formula.ReferenceFieldOrValue; -import org.gridsuite.modification.server.dto.formula.equipmentfield.LoadField; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.LoadField; +import org.gridsuite.modification.server.dto.byfilter.formula.FormulaInfos; +import org.gridsuite.modification.server.dto.byfilter.formula.Operator; +import org.gridsuite.modification.server.dto.byfilter.formula.ReferenceFieldOrValue; import org.gridsuite.modification.server.impacts.AbstractBaseImpact; import java.util.Date; import java.util.List; +import java.util.Set; +import static org.assertj.core.api.Assertions.assertThat; +import static org.gridsuite.modification.server.Impacts.TestImpactUtils.createSubstationImpacts; import static org.gridsuite.modification.server.utils.NetworkUtil.createLoad; import static org.junit.Assert.assertEquals; @@ -114,6 +117,8 @@ protected void assertAfterNetworkModificationDeletion() { @Override protected void assertResultImpacts(List impacts) { - // TODO later + // NOTE: this assert is based on the return of NetworkStoreListener#reduceNetworkImpacts() + // since the test network has only 4 loads which are less than the collectionThreshold 5 + assertThat(impacts).containsAll(createSubstationImpacts(Set.of("s1", "s2"))); } } diff --git a/src/test/java/org/gridsuite/modification/server/modifications/ShuntCompensatorByFormulaModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/ShuntCompensatorByFormulaModificationTest.java similarity index 96% rename from src/test/java/org/gridsuite/modification/server/modifications/ShuntCompensatorByFormulaModificationTest.java rename to src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/ShuntCompensatorByFormulaModificationTest.java index 641b98be0..215c528b6 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/ShuntCompensatorByFormulaModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/ShuntCompensatorByFormulaModificationTest.java @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.modifications; +package org.gridsuite.modification.server.modifications.byfilter.formula; import com.powsybl.iidm.network.IdentifiableType; import com.powsybl.iidm.network.ShuntCompensator; @@ -15,10 +15,10 @@ import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; import org.gridsuite.filter.utils.EquipmentType; -import org.gridsuite.modification.server.dto.formula.FormulaInfos; -import org.gridsuite.modification.server.dto.formula.Operator; -import org.gridsuite.modification.server.dto.formula.ReferenceFieldOrValue; -import org.gridsuite.modification.server.dto.formula.equipmentfield.ShuntCompensatorField; +import org.gridsuite.modification.server.dto.byfilter.formula.FormulaInfos; +import org.gridsuite.modification.server.dto.byfilter.formula.Operator; +import org.gridsuite.modification.server.dto.byfilter.formula.ReferenceFieldOrValue; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.ShuntCompensatorField; import org.junit.Test; import java.util.Date; diff --git a/src/test/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerByFormulaModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/TwoWindingsTransformerByFormulaModificationTest.java similarity index 98% rename from src/test/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerByFormulaModificationTest.java rename to src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/TwoWindingsTransformerByFormulaModificationTest.java index 633bf98ba..c6c1a84ec 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerByFormulaModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/TwoWindingsTransformerByFormulaModificationTest.java @@ -1,4 +1,4 @@ -package org.gridsuite.modification.server.modifications; +package org.gridsuite.modification.server.modifications.byfilter.formula; import com.github.tomakehurst.wiremock.client.WireMock; import com.powsybl.iidm.network.IdentifiableType; @@ -15,10 +15,10 @@ import org.gridsuite.filter.utils.EquipmentType; import org.gridsuite.modification.server.dto.ByFormulaModificationInfos; import org.gridsuite.modification.server.dto.NetworkModificationResult; -import org.gridsuite.modification.server.dto.formula.FormulaInfos; -import org.gridsuite.modification.server.dto.formula.Operator; -import org.gridsuite.modification.server.dto.formula.ReferenceFieldOrValue; -import org.gridsuite.modification.server.dto.formula.equipmentfield.TwoWindingsTransformerField; +import org.gridsuite.modification.server.dto.byfilter.formula.FormulaInfos; +import org.gridsuite.modification.server.dto.byfilter.formula.Operator; +import org.gridsuite.modification.server.dto.byfilter.formula.ReferenceFieldOrValue; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.TwoWindingsTransformerField; import org.junit.Test; import java.util.Date; diff --git a/src/test/java/org/gridsuite/modification/server/modifications/VoltageLevelByFormulaModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/VoltageLevelByFormulaModificationTest.java similarity index 94% rename from src/test/java/org/gridsuite/modification/server/modifications/VoltageLevelByFormulaModificationTest.java rename to src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/VoltageLevelByFormulaModificationTest.java index 44146aba6..fd73c32fd 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/VoltageLevelByFormulaModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/byfilter/formula/VoltageLevelByFormulaModificationTest.java @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.modification.server.modifications; +package org.gridsuite.modification.server.modifications.byfilter.formula; import com.powsybl.iidm.network.IdentifiableType; import com.powsybl.iidm.network.TopologyKind; @@ -16,19 +16,18 @@ import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; import org.gridsuite.filter.utils.EquipmentType; -import org.gridsuite.modification.server.dto.formula.FormulaInfos; -import org.gridsuite.modification.server.dto.formula.Operator; -import org.gridsuite.modification.server.dto.formula.ReferenceFieldOrValue; -import org.gridsuite.modification.server.dto.formula.equipmentfield.VoltageLevelField; +import org.gridsuite.modification.server.dto.byfilter.equipmentfield.VoltageLevelField; +import org.gridsuite.modification.server.dto.byfilter.formula.FormulaInfos; +import org.gridsuite.modification.server.dto.byfilter.formula.Operator; +import org.gridsuite.modification.server.dto.byfilter.formula.ReferenceFieldOrValue; import java.util.Date; import java.util.List; -import static org.gridsuite.modification.server.modifications.ByFormulaModification.EQUIPMENT_MODIFIED_REPORT_ERROR; +import static org.gridsuite.modification.server.modifications.byfilter.AbstractModificationByAssignment.REPORT_KEY_BY_FILTER_MODIFICATION_SOME; +import static org.gridsuite.modification.server.modifications.byfilter.ByFormulaModification.REPORT_KEY_EQUIPMENT_MODIFIED_ERROR; import static org.gridsuite.modification.server.utils.TestUtils.assertLogMessageWithoutRank; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * @author Seddik Yengui @@ -242,8 +241,8 @@ protected void assertAfterNetworkModificationCreation() { assertTrue(Double.isNaN(getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_7).getLowVoltageLimit())); assertTrue(Double.isNaN(getNetwork().getVoltageLevel(VOLTAGE_LEVEL_ID_7).getHighVoltageLimit())); - assertLogMessageWithoutRank("Cannot modify equipment v7 : At least one of the value or referenced field is null", EQUIPMENT_MODIFIED_REPORT_ERROR + "0", reportService); - assertLogMessageWithoutRank("Some of the equipment have been modified : 14 equipment(s) modified and 4 equipment(s) not modified", "byFormulaModificationSome", reportService); + assertLogMessageWithoutRank("Cannot modify equipment v7 : At least one of the value or referenced field is null", REPORT_KEY_EQUIPMENT_MODIFIED_ERROR, reportService); + assertLogMessageWithoutRank("Some of the equipment have been modified : 14 equipment(s) modified and 4 equipment(s) not modified", REPORT_KEY_BY_FILTER_MODIFICATION_SOME, reportService); } @Override