diff --git a/src/main/java/org/gridsuite/modification/modifications/AbstractBranchModification.java b/src/main/java/org/gridsuite/modification/modifications/AbstractBranchModification.java index 6fb1b5c2..01d1b1f0 100644 --- a/src/main/java/org/gridsuite/modification/modifications/AbstractBranchModification.java +++ b/src/main/java/org/gridsuite/modification/modifications/AbstractBranchModification.java @@ -211,8 +211,8 @@ public ReportNode updateMeasurements(Branch branch, BranchModificationInfos b return estimSubReportNode; } - private void upsertMeasurement(Measurements measurements, Measurement.Type type, ThreeSides side, Double value, Boolean validity, List reports) { - if (value == null && validity == null) { + private void upsertMeasurement(Measurements measurements, Measurement.Type type, ThreeSides side, Double value, Boolean requestedValidity, List reports) { + if (value == null && requestedValidity == null) { return; } String measurementType = (type == Measurement.Type.ACTIVE_POWER ? "Active power" : "Reactive power") + " measurement "; @@ -223,10 +223,11 @@ private void upsertMeasurement(Measurements measurements, Measurement.Type ty m.setValue(value); reports.add(ModificationUtils.buildModificationReport(oldValue, value, measurementType + VALUE, TypedValue.INFO_SEVERITY)); } - if (validity != null) { + if (requestedValidity != null) { boolean oldValidity = m.isValid(); - m.setValid(validity); - reports.add(ModificationUtils.buildModificationReport(oldValidity, validity, measurementType + VALIDITY, TypedValue.INFO_SEVERITY)); + + ModificationUtils.updateMeasurementValidity(m, requestedValidity); + reports.add(ModificationUtils.buildModificationReport(oldValidity, requestedValidity, measurementType + VALIDITY, TypedValue.INFO_SEVERITY)); } } else { // add new measurement var mAdder = measurements.newMeasurement().setId(UUID.randomUUID().toString()).setType(type).setSide(side); @@ -234,9 +235,9 @@ private void upsertMeasurement(Measurements measurements, Measurement.Type ty mAdder.setValue(value); reports.add(ModificationUtils.buildModificationReport(null, value, measurementType + VALUE, TypedValue.INFO_SEVERITY)); } - if (validity != null) { - mAdder.setValid(validity); - reports.add(ModificationUtils.buildModificationReport(null, validity, measurementType + VALIDITY, TypedValue.INFO_SEVERITY)); + if (requestedValidity != null) { + mAdder.setValid(requestedValidity); + reports.add(ModificationUtils.buildModificationReport(null, requestedValidity, measurementType + VALIDITY, TypedValue.INFO_SEVERITY)); } mAdder.add(); } diff --git a/src/main/java/org/gridsuite/modification/modifications/AbstractInjectionModification.java b/src/main/java/org/gridsuite/modification/modifications/AbstractInjectionModification.java index d3a4040f..d62f1db6 100644 --- a/src/main/java/org/gridsuite/modification/modifications/AbstractInjectionModification.java +++ b/src/main/java/org/gridsuite/modification/modifications/AbstractInjectionModification.java @@ -60,8 +60,8 @@ protected ReportNode updateMeasurements(Injection injection, InjectionModific return estimSubReportNode; } - private void upsertMeasurement(Measurements measurements, Measurement.Type type, Double value, Boolean validity, List reports) { - if (value == null && validity == null) { + private void upsertMeasurement(Measurements measurements, Measurement.Type type, Double value, Boolean requestedValidity, List reports) { + if (value == null && requestedValidity == null) { return; } String measurementType = (type == Measurement.Type.ACTIVE_POWER ? "Active power" : "Reactive power") + " measurement "; @@ -72,10 +72,11 @@ private void upsertMeasurement(Measurements measurements, Measurement.Type ty measurement.setValue(value); reports.add(ModificationUtils.buildModificationReport(oldValue, value, measurementType + VALUE, TypedValue.INFO_SEVERITY)); } - if (validity != null) { + if (requestedValidity != null) { boolean oldValidity = measurement.isValid(); - measurement.setValid(validity); - reports.add(ModificationUtils.buildModificationReport(oldValidity, validity, measurementType + VALIDITY, TypedValue.INFO_SEVERITY)); + + ModificationUtils.updateMeasurementValidity(measurement, requestedValidity); + reports.add(ModificationUtils.buildModificationReport(oldValidity, requestedValidity, measurementType + VALIDITY, TypedValue.INFO_SEVERITY)); } } else { var measurementAdder = measurements.newMeasurement().setId(UUID.randomUUID().toString()).setType(type); @@ -83,9 +84,9 @@ private void upsertMeasurement(Measurements measurements, Measurement.Type ty measurementAdder.setValue(value); reports.add(ModificationUtils.buildModificationReport(null, value, measurementType + VALUE, TypedValue.INFO_SEVERITY)); } - if (validity != null) { - measurementAdder.setValid(validity); - reports.add(ModificationUtils.buildModificationReport(null, validity, measurementType + VALIDITY, TypedValue.INFO_SEVERITY)); + if (requestedValidity != null) { + measurementAdder.setValid(requestedValidity); + reports.add(ModificationUtils.buildModificationReport(null, requestedValidity, measurementType + VALIDITY, TypedValue.INFO_SEVERITY)); } measurementAdder.add(); } diff --git a/src/main/java/org/gridsuite/modification/utils/ModificationUtils.java b/src/main/java/org/gridsuite/modification/utils/ModificationUtils.java index 0d49e487..874dd4bb 100644 --- a/src/main/java/org/gridsuite/modification/utils/ModificationUtils.java +++ b/src/main/java/org/gridsuite/modification/utils/ModificationUtils.java @@ -72,6 +72,7 @@ public final class ModificationUtils { private static final String COULD_NOT_ACTION_EQUIPMENT_ON_SIDE = COULD_NOT_ACTION_EQUIPMENT + " on side %s"; public static final String CONNECT = "connect"; public static final String DISCONNECT = "disconnect"; + private static final String MEASUREMENT_VALIDITY_PROPERTY = "validity"; public static final String FIELD_MAX_ACTIVE_POWER = "Maximum active power"; public static final String FIELD_MIN_ACTIVE_POWER = "Minimum active power"; public static final String FIELD_PLANNED_ACTIVE_POWER_SET_POINT = "Planned active power set point"; @@ -2193,5 +2194,27 @@ public void createNewActivePowerControlForInjectionCreation(ActivePowerControlAd } } -} + public static void updateMeasurementValidity(Measurement measurement, boolean requestedValidity) { + measurement.setValid(requestedValidity); + if (measurement.getProperty(MEASUREMENT_VALIDITY_PROPERTY) != null) { + if (requestedValidity) { + switch (measurement.getProperty(MEASUREMENT_VALIDITY_PROPERTY)) { + //validity = 1 → TM non valid & not masked + //validity = 3 → TM non valid & masked + case "1": measurement.putProperty(MEASUREMENT_VALIDITY_PROPERTY, "0"); break; + case "3": measurement.putProperty(MEASUREMENT_VALIDITY_PROPERTY, "2"); break; + default: break; + } + } else { + switch (measurement.getProperty(MEASUREMENT_VALIDITY_PROPERTY)) { + //validity = 0 → TM valid & not masked + //validity = 2 → TM valid & masked + case "0": measurement.putProperty(MEASUREMENT_VALIDITY_PROPERTY, "1"); break; + case "2": measurement.putProperty(MEASUREMENT_VALIDITY_PROPERTY, "3"); break; + default: break; + } + } + } + } +} diff --git a/src/test/java/org/gridsuite/modification/modifications/LineModificationTest.java b/src/test/java/org/gridsuite/modification/modifications/LineModificationTest.java index 51fd53da..af5902f9 100644 --- a/src/test/java/org/gridsuite/modification/modifications/LineModificationTest.java +++ b/src/test/java/org/gridsuite/modification/modifications/LineModificationTest.java @@ -591,4 +591,208 @@ void testLimitsPropertiesModificationSameOperationalLimitsReplace() { assertEquals(OLG_PROP3_VALUE, repLimitsGroup2.getProperty(OLG_PROP3_NAME)); } + @Test + void testMeasurementValidityPropertyForLine() { + Line line = getNetwork().getLine("line1"); + Measurements measurements = (Measurements) line.getExtension(Measurements.class); + assertNotNull(measurements); + Measurement activePowerMeasurement = measurements.getMeasurements(Measurement.Type.ACTIVE_POWER).stream() + .filter(m -> m.getSide() == ThreeSides.ONE) + .findFirst() + .orElseThrow(); + + LineModificationInfos addSide1ActiveByValue = LineModificationInfos.builder() + .equipmentId("line1") + .p1MeasurementValue(new AttributeModification<>(79.0, OperationType.SET)) + .build(); + addSide1ActiveByValue.toModification().apply(getNetwork()); + assertEquals(79.0, activePowerMeasurement.getValue()); + + activePowerMeasurement.putProperty("validity", "1"); + LineModificationInfos modificationInfosTrueFromOne = LineModificationInfos.builder() + .equipmentId("line1") + .p1MeasurementValidity(new AttributeModification<>(true, OperationType.SET)) + .build(); + modificationInfosTrueFromOne.toModification().apply(getNetwork()); + assertEquals("0", activePowerMeasurement.getProperty("validity")); + + activePowerMeasurement.putProperty("validity", "3"); + LineModificationInfos modificationInfosTrueFromThree = LineModificationInfos.builder() + .equipmentId("line1") + .p1MeasurementValidity(new AttributeModification<>(true, OperationType.SET)) + .build(); + modificationInfosTrueFromThree.toModification().apply(getNetwork()); + assertEquals("2", activePowerMeasurement.getProperty("validity")); + + Measurement reactivePowerMeasurement = measurements.getMeasurements(Measurement.Type.REACTIVE_POWER).stream() + .filter(m -> m.getSide() == ThreeSides.ONE) + .findFirst() + .orElseThrow(); + reactivePowerMeasurement.putProperty("validity", "2"); + LineModificationInfos modificationInfosFalseFromTwo = LineModificationInfos.builder() + .equipmentId("line1") + .q1MeasurementValidity(new AttributeModification<>(false, OperationType.SET)) + .build(); + modificationInfosFalseFromTwo.toModification().apply(getNetwork()); + assertEquals("3", reactivePowerMeasurement.getProperty("validity")); + + reactivePowerMeasurement.putProperty("validity", "0"); + LineModificationInfos modificationInfosFalseFromZero = LineModificationInfos.builder() + .equipmentId("line1") + .q1MeasurementValidity(new AttributeModification<>(false, OperationType.SET)) + .build(); + modificationInfosFalseFromZero.toModification().apply(getNetwork()); + assertEquals("1", reactivePowerMeasurement.getProperty("validity")); + + // update validity on existing measurement without legacy property + reactivePowerMeasurement.removeProperty("validity"); + LineModificationInfos modificationInfosTrueWithoutProperty = LineModificationInfos.builder() + .equipmentId("line1") + .q1MeasurementValidity(new AttributeModification<>(true, OperationType.SET)) + .build(); + modificationInfosTrueWithoutProperty.toModification().apply(getNetwork()); + assertTrue(reactivePowerMeasurement.isValid()); + assertNull(reactivePowerMeasurement.getProperty("validity")); + + // add side 2 (new) measurement by value only + assertTrue(measurements.getMeasurements(Measurement.Type.ACTIVE_POWER).stream().noneMatch(m -> m.getSide() == ThreeSides.TWO)); + LineModificationInfos addSide2ActiveByValue = LineModificationInfos.builder() + .equipmentId("line1") + .p2MeasurementValue(new AttributeModification<>(42.0, OperationType.SET)) + .build(); + addSide2ActiveByValue.toModification().apply(getNetwork()); + Measurement addedActiveSide2 = measurements.getMeasurements(Measurement.Type.ACTIVE_POWER).stream() + .filter(m -> m.getSide() == ThreeSides.TWO) + .findFirst() + .orElseThrow(); + assertEquals(42.0, addedActiveSide2.getValue()); + + // add side 2 reactive measurement by validity only then update it + assertTrue(measurements.getMeasurements(Measurement.Type.REACTIVE_POWER).stream().noneMatch(m -> m.getSide() == ThreeSides.TWO)); + LineModificationInfos addSide2ReactiveByValidity = LineModificationInfos.builder() + .equipmentId("line1") + .q2MeasurementValue(new AttributeModification<>(MEASUREMENT_Q_VALUE, OperationType.SET)) + .q2MeasurementValidity(new AttributeModification<>(false, OperationType.SET)) + .build(); + addSide2ReactiveByValidity.toModification().apply(getNetwork()); + + Measurement addedReactiveSide2 = measurements.getMeasurements(Measurement.Type.REACTIVE_POWER).stream() + .filter(m -> m.getSide() == ThreeSides.TWO) + .findFirst() + .orElseThrow(); + assertFalse(addedReactiveSide2.isValid()); + + LineModificationInfos updateSide2ReactiveValidity = LineModificationInfos.builder() + .equipmentId("line1") + .q2MeasurementValue(new AttributeModification<>(MEASUREMENT_Q_VALUE, OperationType.SET)) + .q2MeasurementValidity(new AttributeModification<>(true, OperationType.SET)) + .build(); + updateSide2ReactiveValidity.toModification().apply(getNetwork()); + assertTrue(addedReactiveSide2.isValid()); + } + + @Test + void testCreateMeasurementsExtensionWhenMissing() { + Line line = getNetwork().getLine("line2"); + assertNull(line.getExtension(Measurements.class)); + + LineModificationInfos lineModificationInfos = LineModificationInfos.builder() + .equipmentId("line2") + .p1MeasurementValidity(new AttributeModification<>(true, OperationType.SET)) + .p1MeasurementValue(new AttributeModification<>(MEASUREMENT_P_VALUE, OperationType.SET)) + .q1MeasurementValidity(new AttributeModification<>(false, OperationType.SET)) + .q1MeasurementValue(new AttributeModification<>(MEASUREMENT_Q_VALUE, OperationType.SET)) + .build(); + lineModificationInfos.toModification().apply(getNetwork()); + + Measurements measurements = (Measurements) line.getExtension(Measurements.class); + assertNotNull(measurements); + + Measurement p1Measurement = measurements.getMeasurements(Measurement.Type.ACTIVE_POWER).stream() + .filter(m -> m.getSide() == ThreeSides.ONE) + .findFirst() + .orElseThrow(); + assertEquals(10.0, p1Measurement.getValue()); + assertTrue(p1Measurement.isValid()); + + Measurement q1Measurement = measurements.getMeasurements(Measurement.Type.REACTIVE_POWER).stream() + .filter(m -> m.getSide() == ThreeSides.ONE) + .findFirst() + .orElseThrow(); + assertEquals(-10.0, q1Measurement.getValue()); + assertFalse(q1Measurement.isValid()); + } + + @Test + void testCreateMeasurementsExtensionWhenMissingOnlyWithValue() { + Line line = getNetwork().getLine("line2"); + assertNull(line.getExtension(Measurements.class)); + + LineModificationInfos lineModificationInfos = LineModificationInfos.builder() + .equipmentId("line2") + .p1MeasurementValue(new AttributeModification<>(MEASUREMENT_P_VALUE, OperationType.SET)) + .q1MeasurementValue(new AttributeModification<>(MEASUREMENT_Q_VALUE, OperationType.SET)) + .build(); + lineModificationInfos.toModification().apply(getNetwork()); + + Measurements measurements = (Measurements) line.getExtension(Measurements.class); + assertNotNull(measurements); + + Measurement p1Measurement = measurements.getMeasurements(Measurement.Type.ACTIVE_POWER).stream() + .filter(m -> m.getSide() == ThreeSides.ONE) + .findFirst() + .orElseThrow(); + assertEquals(10.0, p1Measurement.getValue()); + assertTrue(p1Measurement.isValid()); // a Measurement is valid by default + + Measurement q1Measurement = measurements.getMeasurements(Measurement.Type.REACTIVE_POWER).stream() + .filter(m -> m.getSide() == ThreeSides.ONE) + .findFirst() + .orElseThrow(); + assertEquals(-10.0, q1Measurement.getValue()); + assertTrue(q1Measurement.isValid()); + } + + @Test + void testCreateMeasurementsExtensionWhenMissingOnlyWithFalseValidity() { + Line line = getNetwork().getLine("line2"); + assertNull(line.getExtension(Measurements.class)); + + LineModificationInfos lineModificationInfos = LineModificationInfos.builder() + .equipmentId("line2") + .p1MeasurementValidity(new AttributeModification<>(false, OperationType.SET)) + .q1MeasurementValidity(new AttributeModification<>(false, OperationType.SET)) + .build(); + lineModificationInfos.toModification().apply(getNetwork()); + + Measurements measurements = (Measurements) line.getExtension(Measurements.class); + assertNotNull(measurements); + + Measurement p1Measurement = measurements.getMeasurements(Measurement.Type.ACTIVE_POWER).stream() + .filter(m -> m.getSide() == ThreeSides.ONE) + .findFirst() + .orElseThrow(); + assertTrue(Double.isNaN(p1Measurement.getValue())); + assertFalse(p1Measurement.isValid()); + + Measurement q1Measurement = measurements.getMeasurements(Measurement.Type.REACTIVE_POWER).stream() + .filter(m -> m.getSide() == ThreeSides.ONE) + .findFirst() + .orElseThrow(); + assertTrue(Double.isNaN(q1Measurement.getValue())); + assertFalse(q1Measurement.isValid()); + } + + @Test + void testCannotCreateMeasurementsExtensionWhenMissingWithOnlyTrueValidity() { + Line line = getNetwork().getLine("line2"); + assertNull(line.getExtension(Measurements.class)); + + LineModificationInfos lineModificationInfos = LineModificationInfos.builder() + .equipmentId("line2") + .p1MeasurementValidity(new AttributeModification<>(true, OperationType.SET)) // not allowed by powsybl on extension creation + .build(); + PowsyblException e = assertThrows(PowsyblException.class, () -> lineModificationInfos.toModification().apply(getNetwork())); + assertEquals("Valid measurement cannot have an undefined value", e.getMessage()); + } } diff --git a/src/test/java/org/gridsuite/modification/modifications/LoadModificationTest.java b/src/test/java/org/gridsuite/modification/modifications/LoadModificationTest.java index a52f0a62..4f9c94aa 100644 --- a/src/test/java/org/gridsuite/modification/modifications/LoadModificationTest.java +++ b/src/test/java/org/gridsuite/modification/modifications/LoadModificationTest.java @@ -13,11 +13,16 @@ import com.powsybl.iidm.network.ValidationException; import com.powsybl.iidm.network.extensions.Measurement; import com.powsybl.iidm.network.extensions.Measurements; +import com.powsybl.iidm.network.extensions.MeasurementsAdder; import org.apache.commons.collections4.CollectionUtils; import org.gridsuite.modification.dto.*; import org.gridsuite.modification.utils.NetworkCreation; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; import java.util.Collection; import java.util.List; @@ -113,4 +118,169 @@ void testDisconnection() throws Exception { void testConnection() throws Exception { assertChangeConnectionState(getNetwork().getLoad("v1load"), true); } + + @MethodSource("validityExpectedValuesAfterModification") + @ParameterizedTest(name = "[{index}] Apply validity {0} on actual property {1} should give {2}") + void testUpsertMeasurementPropertyCombinations(final boolean modificationValidity, final String actualPropertyState, final String expectedPropertyState) { + Load load = getNetwork().getLoad("v1load"); + Measurements measurements = (Measurements) load.getExtension(Measurements.class); + if (measurements == null) { + measurements = (Measurements) load.newExtension(MeasurementsAdder.class).add(); + } + + // active power test + Measurement activePowerMeasurement = measurements.newMeasurement() + .setId(UUID.randomUUID().toString()) + .setType(Measurement.Type.ACTIVE_POWER) + .setValue(5.0) + .setValid(true) + .add(); + activePowerMeasurement.putProperty("validity", actualPropertyState); + LoadModificationInfos activePowerModification = LoadModificationInfos.builder() + .equipmentId("v1load") + .pMeasurementValidity(new AttributeModification<>(modificationValidity, OperationType.SET)) + .build(); + activePowerModification.toModification().apply(getNetwork()); + assertEquals(expectedPropertyState, activePowerMeasurement.getProperty("validity")); + assertEquals(modificationValidity, activePowerMeasurement.isValid()); + + // reactive power test + Measurement reactivePowerMeasurement = measurements.newMeasurement() + .setId(UUID.randomUUID().toString()) + .setType(Measurement.Type.REACTIVE_POWER) + .setValue(-5.0) + .setValid(false) + .add(); + reactivePowerMeasurement.putProperty("validity", actualPropertyState); + LoadModificationInfos reactivePowerModification = LoadModificationInfos.builder() + .equipmentId("v1load") + .qMeasurementValidity(new AttributeModification<>(modificationValidity, OperationType.SET)) + .build(); + reactivePowerModification.toModification().apply(getNetwork()); + assertEquals(expectedPropertyState, reactivePowerMeasurement.getProperty("validity")); + assertEquals(modificationValidity, activePowerMeasurement.isValid()); + } + + public static List validityExpectedValuesAfterModification() { + return List.of( + Arguments.of(true, "0", "0"), + Arguments.of(true, "1", "0"), + Arguments.of(true, "2", "2"), + Arguments.of(true, "3", "2"), + Arguments.of(false, "0", "1"), + Arguments.of(false, "1", "1"), + Arguments.of(false, "2", "3"), + Arguments.of(false, "3", "3") + ); + } + + @ValueSource(strings = {"0", "1", "2", "3"}) + @ParameterizedTest + void testUpsertMeasurementValueChangedPropertyNotChanged(final String propertyState) { + Load load = getNetwork().getLoad("v1load"); + Measurements measurements = (Measurements) load.getExtension(Measurements.class); + if (measurements == null) { + measurements = (Measurements) load.newExtension(MeasurementsAdder.class).add(); + } + // Changing only the TM value will not change the validity + final double newValue = 10.; + + // active power test + Measurement activePowerMeasurement = measurements.newMeasurement() + .setId(UUID.randomUUID().toString()) + .setType(Measurement.Type.ACTIVE_POWER) + .setValue(5.0) + .setValid(true) + .add(); + activePowerMeasurement.putProperty("validity", propertyState); + LoadModificationInfos updateActiveValidityTrue = LoadModificationInfos.builder() + .equipmentId("v1load") + .pMeasurementValue(new AttributeModification<>(newValue, OperationType.SET)) + .build(); + updateActiveValidityTrue.toModification().apply(getNetwork()); + assertEquals(propertyState, activePowerMeasurement.getProperty("validity")); + assertEquals(newValue, activePowerMeasurement.getValue()); + + // reactive power test + Measurement reactivePowerMeasurement = measurements.newMeasurement() + .setId(UUID.randomUUID().toString()) + .setType(Measurement.Type.REACTIVE_POWER) + .setValue(-5.0) + .setValid(false) + .add(); + reactivePowerMeasurement.putProperty("validity", propertyState); + LoadModificationInfos updateReactiveValidityFalse = LoadModificationInfos.builder() + .equipmentId("v1load") + .qMeasurementValue(new AttributeModification<>(newValue, OperationType.SET)) + .build(); + updateReactiveValidityFalse.toModification().apply(getNetwork()); + assertEquals(propertyState, reactivePowerMeasurement.getProperty("validity")); + assertEquals(newValue, activePowerMeasurement.getValue()); + } + + @Test + void testCreateMeasurementsExtensionWhenMissingOnlyWithValue() { + Load load = getNetwork().getLoad("v2load"); + Measurements measurements = (Measurements) load.getExtension(Measurements.class); + assertNull(measurements); + + // active power test + LoadModificationInfos updateActiveValue = LoadModificationInfos.builder() + .equipmentId("v2load") + .pMeasurementValue(new AttributeModification<>(66.5, OperationType.SET)) + .build(); + updateActiveValue.toModification().apply(getNetwork()); + + measurements = (Measurements) load.getExtension(Measurements.class); + assertNotNull(measurements); + Measurement activePowerMeasurement = measurements.getMeasurements(Measurement.Type.ACTIVE_POWER).stream().findFirst().orElse(null); + assertNotNull(activePowerMeasurement); + assertEquals(66.5, activePowerMeasurement.getValue()); + assertTrue(activePowerMeasurement.isValid()); + + // reactive power test + LoadModificationInfos updateReactiveValue = LoadModificationInfos.builder() + .equipmentId("v2load") + .qMeasurementValue(new AttributeModification<>(99.5, OperationType.SET)) + .build(); + updateReactiveValue.toModification().apply(getNetwork()); + + Measurement reactivePowerMeasurement = measurements.getMeasurements(Measurement.Type.REACTIVE_POWER).stream().findFirst().orElse(null); + assertNotNull(reactivePowerMeasurement); + assertEquals(99.5, reactivePowerMeasurement.getValue()); + assertTrue(reactivePowerMeasurement.isValid()); + } + + @Test + void testCreateMeasurementsExtensionWhenMissingOnlyWithFalseValidity() { + Load load = getNetwork().getLoad("v2load"); + Measurements measurements = (Measurements) load.getExtension(Measurements.class); + assertNull(measurements); + + // active power test + LoadModificationInfos updateActiveValidity = LoadModificationInfos.builder() + .equipmentId("v2load") + .pMeasurementValidity(new AttributeModification<>(false, OperationType.SET)) + .build(); + updateActiveValidity.toModification().apply(getNetwork()); + + measurements = (Measurements) load.getExtension(Measurements.class); + assertNotNull(measurements); + Measurement activePowerMeasurement = measurements.getMeasurements(Measurement.Type.ACTIVE_POWER).stream().findFirst().orElse(null); + assertNotNull(activePowerMeasurement); + assertTrue(Double.isNaN(activePowerMeasurement.getValue())); + assertFalse(activePowerMeasurement.isValid()); + + // reactive power test + LoadModificationInfos updateReactiveValidity = LoadModificationInfos.builder() + .equipmentId("v2load") + .qMeasurementValidity(new AttributeModification<>(false, OperationType.SET)) + .build(); + updateReactiveValidity.toModification().apply(getNetwork()); + + Measurement reactivePowerMeasurement = measurements.getMeasurements(Measurement.Type.REACTIVE_POWER).stream().findFirst().orElse(null); + assertNotNull(reactivePowerMeasurement); + assertTrue(Double.isNaN(reactivePowerMeasurement.getValue())); + assertFalse(reactivePowerMeasurement.isValid()); + } } diff --git a/src/test/java/org/gridsuite/modification/modifications/TwoWindingsTransformerModificationTest.java b/src/test/java/org/gridsuite/modification/modifications/TwoWindingsTransformerModificationTest.java index 7781bc4d..55621b0e 100644 --- a/src/test/java/org/gridsuite/modification/modifications/TwoWindingsTransformerModificationTest.java +++ b/src/test/java/org/gridsuite/modification/modifications/TwoWindingsTransformerModificationTest.java @@ -9,10 +9,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.powsybl.commons.report.ReportNode; import com.powsybl.iidm.network.*; -import com.powsybl.iidm.network.extensions.ConnectablePosition; -import com.powsybl.iidm.network.extensions.Measurement; -import com.powsybl.iidm.network.extensions.Measurements; -import com.powsybl.iidm.network.extensions.TwoWindingsTransformerToBeEstimated; +import com.powsybl.iidm.network.extensions.*; import org.apache.commons.collections4.CollectionUtils; import org.gridsuite.modification.NetworkModificationException; import org.gridsuite.modification.dto.*; @@ -1060,5 +1057,59 @@ void testProcessPhaseTapChangerRegulationModificationWithRegulating() { assertTrue(phaseTapChanger.isRegulating()); } + @Test + void testMeasurementValidityPropertyForTransformer() { + TwoWindingsTransformer transformer = getNetwork().getTwoWindingsTransformer("trf1"); + Measurements measurements = (Measurements) transformer.getExtension(Measurements.class); + if (measurements == null) { + measurements = (Measurements) transformer.newExtension(MeasurementsAdder.class).add(); + } + Measurement activePowerMeasurement = measurements.newMeasurement() + .setId(UUID.randomUUID().toString()) + .setType(Measurement.Type.ACTIVE_POWER) + .setSide(ThreeSides.ONE) + .setValue(11.0) + .setValid(true) + .add(); + + activePowerMeasurement.putProperty("validity", "1"); + TwoWindingsTransformerModificationInfos modificationInfosTrueFromOne = TwoWindingsTransformerModificationInfos.builder() + .equipmentId("trf1") + .p1MeasurementValidity(new AttributeModification<>(true, OperationType.SET)) + .build(); + modificationInfosTrueFromOne.toModification().apply(getNetwork()); + assertEquals("0", activePowerMeasurement.getProperty("validity")); + + activePowerMeasurement.putProperty("validity", "3"); + TwoWindingsTransformerModificationInfos modificationInfosTrueFromThree = TwoWindingsTransformerModificationInfos.builder() + .equipmentId("trf1") + .p1MeasurementValidity(new AttributeModification<>(true, OperationType.SET)) + .build(); + modificationInfosTrueFromThree.toModification().apply(getNetwork()); + assertEquals("2", activePowerMeasurement.getProperty("validity")); + + Measurement reactivePowerMeasurement = measurements.newMeasurement() + .setId(UUID.randomUUID().toString()) + .setType(Measurement.Type.REACTIVE_POWER) + .setSide(ThreeSides.ONE) + .setValue(-11.0) + .setValid(false) + .add(); + reactivePowerMeasurement.putProperty("validity", "2"); + TwoWindingsTransformerModificationInfos modificationInfosFalseFromTwo = TwoWindingsTransformerModificationInfos.builder() + .equipmentId("trf1") + .q1MeasurementValidity(new AttributeModification<>(false, OperationType.SET)) + .build(); + modificationInfosFalseFromTwo.toModification().apply(getNetwork()); + assertEquals("3", reactivePowerMeasurement.getProperty("validity")); + + reactivePowerMeasurement.putProperty("validity", "0"); + TwoWindingsTransformerModificationInfos modificationInfosFalseFromZero = TwoWindingsTransformerModificationInfos.builder() + .equipmentId("trf1") + .q1MeasurementValidity(new AttributeModification<>(false, OperationType.SET)) + .build(); + modificationInfosFalseFromZero.toModification().apply(getNetwork()); + assertEquals("1", reactivePowerMeasurement.getProperty("validity")); + } }