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 index a7d2ea60e..aaae6b502 100644 --- a/src/main/java/org/gridsuite/modification/server/dto/formula/ReferenceFieldOrValue.java +++ b/src/main/java/org/gridsuite/modification/server/dto/formula/ReferenceFieldOrValue.java @@ -13,6 +13,7 @@ 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; @@ -24,6 +25,7 @@ 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; @@ -52,21 +54,15 @@ public Double getRefOrValue(Identifiable identifiable) { } IdentifiableType identifiableType = identifiable.getType(); - Double referenceValue = switch (identifiableType) { + 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())); }; - - if (referenceValue == null) { - throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, - String.format("value of %s is null", equipmentField)); - } - - return referenceValue; } } 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 new file mode 100644 index 000000000..e784d9744 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java @@ -0,0 +1,70 @@ +package org.gridsuite.modification.server.dto.formula.equipmentfield; + +import com.powsybl.iidm.network.PhaseTapChanger; +import com.powsybl.iidm.network.RatioTapChanger; +import com.powsybl.iidm.network.TwoWindingsTransformer; + +public enum TwoWindingsTransformerField { + SERIES_RESISTANCE, + SERIES_REACTANCE, + MAGNETIZING_CONDUCTANCE, + MAGNETIZING_SUSCEPTANCE, + RATED_VOLTAGE_1, + RATED_VOLTAGE_2, + RATED_S, + TARGET_V, + RATIO_LOW_TAP_POSITION, + RATIO_TAP_POSITION, + RATIO_TARGET_DEADBAND, + REGULATION_VALUE, + PHASE_LOW_TAP_POSITION, + PHASE_TAP_POSITION, + PHASE_TARGET_DEADBAND; + + public static Double getReferenceValue(TwoWindingsTransformer transformer, String twoWindingsTransformerField) { + TwoWindingsTransformerField field = TwoWindingsTransformerField.valueOf(twoWindingsTransformerField); + final PhaseTapChanger phaseTapChanger = transformer.getPhaseTapChanger(); + final RatioTapChanger ratioTapChanger = transformer.getRatioTapChanger(); + return switch (field) { + case SERIES_RESISTANCE -> transformer.getR(); + case SERIES_REACTANCE -> transformer.getX(); + case MAGNETIZING_CONDUCTANCE -> transformer.getG(); + case MAGNETIZING_SUSCEPTANCE -> transformer.getB(); + case RATED_VOLTAGE_1 -> transformer.getRatedU1(); + case RATED_VOLTAGE_2 -> 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; + }; + } + + public static void setNewValue(TwoWindingsTransformer transformer, String twoWindingsTransformerField, Double newValue) { + TwoWindingsTransformerField field = TwoWindingsTransformerField.valueOf(twoWindingsTransformerField); + final PhaseTapChanger phaseTapChanger = transformer.getPhaseTapChanger(); + final RatioTapChanger ratioTapChanger = transformer.getRatioTapChanger(); + + switch (field) { + case SERIES_RESISTANCE -> transformer.setR(newValue); + case SERIES_REACTANCE -> transformer.setX(newValue); + case MAGNETIZING_CONDUCTANCE -> transformer.setG(newValue); + case MAGNETIZING_SUSCEPTANCE -> transformer.setB(newValue); + case RATED_VOLTAGE_1 -> transformer.setRatedU1(newValue); + case RATED_VOLTAGE_2 -> 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); + } + } +} 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 6e8a62a61..b12f9fd11 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java @@ -13,9 +13,11 @@ 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.Network; import com.powsybl.iidm.network.ShuntCompensator; +import com.powsybl.iidm.network.TwoWindingsTransformer; import com.powsybl.iidm.network.VoltageLevel; import org.gridsuite.modification.server.NetworkModificationException; import org.gridsuite.modification.server.dto.ByFormulaModificationInfos; @@ -27,8 +29,10 @@ 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; import org.gridsuite.modification.server.service.FilterService; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.springframework.util.CollectionUtils; @@ -44,9 +48,11 @@ public class ByFormulaModification extends AbstractModification { private final ByFormulaModificationInfos modificationInfos; protected FilterService filterService; + private int equipmentNotModifiedCount; public ByFormulaModification(ByFormulaModificationInfos modificationInfos) { this.modificationInfos = modificationInfos; + equipmentNotModifiedCount = 0; } @Override @@ -80,22 +86,53 @@ public void apply(Network network, Reporter subReporter) { Map exportFilters = getUuidFilterEquipmentsMap(network, subReporter, filters); if (exportFilters != null) { + long equipmentCount = exportFilters.values() + .stream() + .filter(filterEquipments -> !CollectionUtils.isEmpty(filterEquipments.getIdentifiableAttributes())) + .mapToLong(filterEquipments -> filterEquipments.getIdentifiableAttributes().size()) + .sum(); + long equipmentNotFoundCount = exportFilters.values() + .stream() + .filter(filterEquipments -> !CollectionUtils.isEmpty(filterEquipments.getNotFoundEquipments())) + .mapToLong(filterEquipments -> filterEquipments.getNotFoundEquipments().size()) + .sum(); Reporter formulaSubReporter = subReporter.createSubReporter("appliedFormulasModifications", "Formulas"); List formulaReports = new ArrayList<>(); modificationInfos.getFormulaInfosList().forEach(formulaInfos -> formulaInfos.getFilters().forEach(filterInfos -> applyFormulaOnFilterEquipments(network, exportFilters, formulaReports, formulaInfos, filterInfos))); - createReport(subReporter, "byFormulaModification", "new modification by formula", TypedValue.INFO_SEVERITY); - formulaSubReporter.report(Report.builder() - .withKey("appliedFormulasModifications") - .withDefaultMessage(" Formulas") - .withSeverity(TypedValue.INFO_SEVERITY) - .build()); - formulaReports.forEach(formulaSubReporter::report); + createReport(subReporter, "byFormulaModification", "New modification by formula", TypedValue.INFO_SEVERITY); + if (equipmentNotModifiedCount == 0 && equipmentNotFoundCount == 0) { + createReport(subReporter, "byFormulaModificationALL", + String.format("All equipment have been modified : %s equipment(s)", equipmentCount), + TypedValue.INFO_SEVERITY); + report(formulaSubReporter, formulaReports); + } else { + if (equipmentNotModifiedCount == equipmentCount) { + createReport(subReporter, "byFormulaModificationNone", + "No equipment have been modified", + TypedValue.ERROR_SEVERITY); + } else { + createReport(subReporter, "byFormulaModificationSome", + String.format("Some of the equipment have been modified : %s equipment(s) modified and %s equipment(s) not modified", + equipmentCount - equipmentNotModifiedCount, equipmentNotModifiedCount + equipmentNotFoundCount), + TypedValue.WARN_SEVERITY); + report(formulaSubReporter, formulaReports); + } + } } } + private void report(Reporter formulaSubReporter, List formulaReports) { + formulaSubReporter.report(Report.builder() + .withKey("appliedFormulasModifications") + .withDefaultMessage(" Formulas") + .withSeverity(TypedValue.INFO_SEVERITY) + .build()); + formulaReports.forEach(formulaSubReporter::report); + } + private void applyFormulaOnFilterEquipments(Network network, Map exportFilters, List formulaReports, @@ -103,16 +140,70 @@ private void applyFormulaOnFilterEquipments(Network network, FilterInfos filterInfos) { FilterEquipments filterEquipments = exportFilters.get(filterInfos.getId()); - formulaReports.add(Report.builder() - .withKey("byFormulaModificationFormulaFilter_" + formulaReports.size()) - .withDefaultMessage(String.format("Successful application of new modification by formula on filter %s", - filterInfos.getName())) - .withSeverity(TypedValue.INFO_SEVERITY) - .build()); + if (CollectionUtils.isEmpty(filterEquipments.getIdentifiableAttributes())) { + formulaReports.add(Report.builder() + .withKey("byFormulaModificationFormulaFilter_" + formulaReports.size()) + .withDefaultMessage(String.format("No equipments were found for filter %s", + filterInfos.getName())) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } else { + List notEditableEquipments = new ArrayList<>(); + List equipmentsReport = new ArrayList<>(); + filterEquipments.getIdentifiableAttributes() + .stream() + .map(attributes -> network.getIdentifiable(attributes.getId())) + .filter(identifiable -> { + boolean isEditableEquipment = isEquipmentEditable(identifiable, formulaInfos); + 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(Report.builder() + .withKey("byFormulaModificationFormulaFilterFailed_" + formulaReports.size()) + .withDefaultMessage(String.format("No equipment(s) have been modified on filter %s", + filterInfos.getName())) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } else { + formulaReports.add(Report.builder() + .withKey("byFormulaModificationFormulaFilter_" + formulaReports.size()) + .withDefaultMessage(String.format("Successful application of new modification by formula on filter %s", + filterInfos.getName())) + .withSeverity(TypedValue.INFO_SEVERITY) + .build()); + + formulaReports.add(Report.builder() + .withKey("numberOfValidEquipment" + formulaReports.size()) + .withDefaultMessage(String.format(" Number of equipment modified : %s", + filterEquipments.getIdentifiableAttributes().size() - notEditableEquipments.size())) + .withSeverity(TypedValue.INFO_SEVERITY) + .build()); + + if (!CollectionUtils.isEmpty(notEditableEquipments)) { + formulaReports.add(Report.builder() + .withKey("NotEditedEquipmentsFilter_" + formulaReports.size()) + .withDefaultMessage(String.format(" The following equipment were not modified : %s", String.join(", ", notEditableEquipments))) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } + } formulaReports.add(Report.builder() - .withKey("numberOfValidEquipment" + formulaReports.size()) - .withDefaultMessage(String.format(" Number of equipment modified : %s", filterEquipments.getIdentifiableAttributes().size())) + .withKey("editedFieldFilter_" + formulaReports.size()) + .withDefaultMessage(String.format(" Edited field : %s", formulaInfos.getEditedField())) .withSeverity(TypedValue.INFO_SEVERITY) .build()); @@ -125,17 +216,6 @@ private void applyFormulaOnFilterEquipments(Network network, .withSeverity(TypedValue.WARN_SEVERITY) .build()); } - - formulaReports.add(Report.builder() - .withKey("editedFieldFilter_" + formulaReports.size()) - .withDefaultMessage(String.format(" Edited field : %s", formulaInfos.getEditedField())) - .withSeverity(TypedValue.INFO_SEVERITY) - .build()); - - filterEquipments.getIdentifiableAttributes().forEach(attributes -> applyFormula(network, - attributes.getId(), - formulaInfos, - formulaReports)); } @Nullable @@ -147,53 +227,84 @@ private Map getUuidFilterEquipmentsMap(Network network, return isValidFilter ? exportFilters : null; } - private void applyFormula(Network network, - String identifiableId, - FormulaInfos formulaInfos, - List reports) { - Identifiable identifiable = network.getIdentifiable(identifiableId); - Double value1 = formulaInfos.getFieldOrValue1().getRefOrValue(identifiable); - Double value2 = formulaInfos.getFieldOrValue2().getRefOrValue(identifiable); - final Double newValue = applyOperation(formulaInfos.getOperator(), value1, value2); - switch (identifiable.getType()) { - case GENERATOR -> GeneratorField.setNewValue((Generator) identifiable, formulaInfos.getEditedField(), newValue); - 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); - default -> throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, "Unsupported equipment"); + private boolean isEquipmentEditable(Identifiable identifiable, + FormulaInfos formulaInfos) { + if (formulaInfos.getEditedField() == null) { + return false; } - reports.add(Report.builder() - .withKey("EquipmentModifiedReport_" + reports.size()) - .withDefaultMessage(String.format(" %s id : %s, new value of %s : %s", - modificationInfos.getIdentifiableType(), - identifiable.getId(), - formulaInfos.getEditedField(), - newValue)) - .withSeverity(TypedValue.TRACE_SEVERITY) - .build()); + 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 -> twoWindingsTransformer.getRatioTapChanger() != null; + case REGULATION_VALUE, PHASE_LOW_TAP_POSITION, PHASE_TAP_POSITION, PHASE_TARGET_DEADBAND -> twoWindingsTransformer.getPhaseTapChanger() != null; + default -> true; + }; + } + return true; } - private Double applyOperation(Operator operator, Double value1, Double value2) { - if (value1 == null || - value2 == null) { - throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, "at least one of the value or referenced field is null"); + 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 || value2 == null) { + equipmentNotModifiedCount += 1; + notEditableEquipments.add(identifiable.getId()); + reports.add(Report.builder() + .withKey("EquipmentModifiedReportError_" + reports.size()) + .withDefaultMessage(String.format(" Cannot modify equipment %s : At least one of the value or referenced field is null", + identifiable.getId())) + .withSeverity(TypedValue.TRACE_SEVERITY) + .build()); + } else if (value2 == 0 && formulaInfos.getOperator() == Operator.DIVISION) { + equipmentNotModifiedCount += 1; + notEditableEquipments.add(identifiable.getId()); } else { - return switch (operator) { - case ADDITION -> value1 + value2; - case SUBTRACTION -> value1 - value2; - case MULTIPLICATION -> value1 * value2; - case DIVISION -> { - if (value2 == 0) { - throw new NetworkModificationException(NetworkModificationException.Type.BY_FORMULA_MODIFICATION_ERROR, - "there is a division by zero in a formula"); - } else { - yield value1 / value2; - } + try { + final Double newValue = applyOperation(formulaInfos.getOperator(), value1, value2); + switch (identifiable.getType()) { + case GENERATOR -> GeneratorField.setNewValue((Generator) identifiable, formulaInfos.getEditedField(), newValue); + 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"); } - case PERCENTAGE -> value1 * (value2 / 100); - }; + reports.add(Report.builder() + .withKey("EquipmentModifiedReport_" + reports.size()) + .withDefaultMessage(String.format(" %s id : %s, new value of %s : %s", + modificationInfos.getIdentifiableType(), + identifiable.getId(), + formulaInfos.getEditedField(), + newValue)) + .withSeverity(TypedValue.TRACE_SEVERITY) + .build()); + } catch (Exception e) { + notEditableEquipments.add(identifiable.getId()); + equipmentNotModifiedCount += 1; + reports.add(Report.builder() + .withKey("EquipmentModifiedReportExceptionf_" + reports.size()) + .withDefaultMessage(String.format(" Cannot modify equipment %s : %s", + identifiable.getId(), + 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/ModificationUtils.java b/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java index 3504f273b..a144a16e8 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java @@ -1017,7 +1017,7 @@ public boolean isValidFilter(Reporter subReporter, NetworkModificationException.Type errorType, Map exportFilters) { boolean noValidEquipmentId = exportFilters.values().stream() - .allMatch(filterEquipments -> filterEquipments.getIdentifiableAttributes().isEmpty()); + .allMatch(filterEquipments -> CollectionUtils.isEmpty(filterEquipments.getIdentifiableAttributes())); if (noValidEquipmentId) { String errorMsg = errorType + ": There is no valid equipment ID among the provided filter(s)"; diff --git a/src/test/java/org/gridsuite/modification/server/modifications/AbstractByFormulaModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/AbstractByFormulaModificationTest.java index 81c010149..e08660a8b 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/AbstractByFormulaModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/AbstractByFormulaModificationTest.java @@ -70,6 +70,23 @@ public void specificSetUp() { createEquipments(); } + @Test + public void testByModificationError() throws Exception { + // Test with empty list of formulas + checkCreationApplicationStatus(ByFormulaModificationInfos.builder().identifiableType(getIdentifiableType()).formulaInfosList(List.of()).build(), + NetworkModificationResult.ApplicationStatus.WITH_ERRORS); + + // Test with empty list of filters in formula + FormulaInfos formulaInfos = FormulaInfos.builder() + .fieldOrValue1(ReferenceFieldOrValue.builder().value(50.).build()) + .fieldOrValue2(ReferenceFieldOrValue.builder().value(50.).build()) + .operator(Operator.ADDITION) + .filters(List.of()) + .build(); + checkCreationApplicationStatus(ByFormulaModificationInfos.builder().identifiableType(getIdentifiableType()).formulaInfosList(List.of(formulaInfos)).build(), + NetworkModificationResult.ApplicationStatus.WITH_ERRORS); + } + protected void checkCreateWithWarning(List formulaInfos, List existingEquipmentList) throws Exception { FilterEquipments filter = getFilterEquipments(FILTER_WITH_ONE_WRONG_ID, "filterWithWrongId", existingEquipmentList, List.of("wrongId")); @@ -135,7 +152,7 @@ public void testCopy() throws Exception { wireMockUtils.verifyGetRequest(stubId, PATH, handleQueryParams(getNetworkUuid(), filters.stream().map(FilterEquipments::getFilterId).collect(Collectors.toList())), false); } - private void checkCreationApplicationStatus(ByFormulaModificationInfos byFormulaModificationInfos, + protected void checkCreationApplicationStatus(ByFormulaModificationInfos byFormulaModificationInfos, NetworkModificationResult.ApplicationStatus applicationStatus) throws Exception { String modificationToCreateJson = mapper.writeValueAsString(byFormulaModificationInfos); @@ -201,11 +218,11 @@ protected FormulaInfos getFormulaInfo(String editedField, .build(); } - private Map handleQueryParams(UUID networkUuid, List filterIds) { + Map handleQueryParams(UUID networkUuid, List filterIds) { return Map.of("networkUuid", WireMock.equalTo(String.valueOf(networkUuid)), "variantId", WireMock.equalTo("variant_1"), "ids", WireMock.matching(filterIds.stream().map(uuid -> ".+").collect(Collectors.joining(",")))); } - private String getPath(UUID networkUuid, boolean isRegexPhat) { + String getPath(UUID networkUuid, boolean isRegexPhat) { if (isRegexPhat) { return "/v1/filters/export\\?networkUuid=" + networkUuid + "\\&variantId=variant_1\\&ids="; } diff --git a/src/test/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerByFormulaModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerByFormulaModificationTest.java new file mode 100644 index 000000000..b3d78c507 --- /dev/null +++ b/src/test/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerByFormulaModificationTest.java @@ -0,0 +1,576 @@ +package org.gridsuite.modification.server.modifications; + +import com.github.tomakehurst.wiremock.client.WireMock; +import com.powsybl.iidm.network.IdentifiableType; +import com.powsybl.iidm.network.PhaseTapChanger; +import com.powsybl.iidm.network.PhaseTapChangerAdder; +import com.powsybl.iidm.network.RatioTapChanger; +import com.powsybl.iidm.network.RatioTapChangerAdder; +import com.powsybl.iidm.network.Substation; +import com.powsybl.iidm.network.TwoWindingsTransformer; +import com.powsybl.iidm.network.extensions.ConnectablePosition; +import org.gridsuite.modification.server.dto.ByFormulaModificationInfos; +import org.gridsuite.modification.server.dto.FilterEquipments; +import org.gridsuite.modification.server.dto.IdentifiableAttributes; +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.junit.Test; + +import java.util.List; +import java.util.UUID; + +import static org.gridsuite.modification.server.utils.NetworkUtil.createTwoWindingsTransformer; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class TwoWindingsTransformerByFormulaModificationTest extends AbstractByFormulaModificationTest { + 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 { + IdentifiableAttributes identifiableAttributes1 = getIdentifiableAttributes(TWT_ID_4, 1.); + IdentifiableAttributes identifiableAttributes2 = getIdentifiableAttributes(TWT_ID_6, 1.); + FilterEquipments filter = getFilterEquipments(FILTER_ID_4, "filter4", List.of(identifiableAttributes1, identifiableAttributes2), List.of()); + + UUID stubId = wireMockServer.stubFor(WireMock.get(WireMock.urlMatching("/v1/filters/export\\?networkUuid=" + getNetworkUuid() + "&variantId=variant_1&ids=" + FILTER_ID_4)) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(List.of(filter))) + .withHeader("Content-Type", "application/json"))).getId(); + FormulaInfos formulaInfos = FormulaInfos.builder() + .filters(List.of(filter4)) + .fieldOrValue2(ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.RATIO_TAP_POSITION.name()).build()) + .fieldOrValue1(ReferenceFieldOrValue.builder().value(1.).build()) + .editedField(TwoWindingsTransformerField.RATIO_TAP_POSITION.name()) + .operator(Operator.ADDITION) + .build(); + checkCreationApplicationStatus(ByFormulaModificationInfos.builder() + .identifiableType(getIdentifiableType()) + .formulaInfosList(List.of(formulaInfos)) + .build(), + NetworkModificationResult.ApplicationStatus.WITH_ERRORS); + + assertNull(getNetwork().getTwoWindingsTransformer(TWT_ID_4).getRatioTapChanger()); + assertNull(getNetwork().getTwoWindingsTransformer(TWT_ID_6).getRatioTapChanger()); + + wireMockUtils.verifyGetRequest(stubId, PATH, handleQueryParams(getNetworkUuid(), List.of(FILTER_ID_4)), false); + } + + @Test + public void testDivisionByZero() throws Exception { + IdentifiableAttributes identifiableAttributes1 = getIdentifiableAttributes(TWT_ID_4, 1.); + IdentifiableAttributes identifiableAttributes2 = getIdentifiableAttributes(TWT_ID_6, 1.); + FilterEquipments filter = getFilterEquipments(FILTER_ID_4, "filter4", List.of(identifiableAttributes1, identifiableAttributes2), List.of()); + + UUID stubId = wireMockServer.stubFor(WireMock.get(WireMock.urlMatching("/v1/filters/export\\?networkUuid=" + getNetworkUuid() + "&variantId=variant_1&ids=" + FILTER_ID_4)) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(List.of(filter))) + .withHeader("Content-Type", "application/json"))).getId(); + + // Test division by 0 + FormulaInfos formulaInfos2 = FormulaInfos.builder() + .fieldOrValue1(ReferenceFieldOrValue.builder().value(50.).build()) + .fieldOrValue2(ReferenceFieldOrValue.builder().value(0.).build()) + .operator(Operator.DIVISION) + .filters(List.of(filter4)) + .build(); + + checkCreationApplicationStatus(ByFormulaModificationInfos.builder().identifiableType(getIdentifiableType()).formulaInfosList(List.of(formulaInfos2)).build(), + NetworkModificationResult.ApplicationStatus.WITH_ERRORS); + + wireMockUtils.verifyGetRequest(stubId, PATH, handleQueryParams(getNetworkUuid(), List.of(FILTER_ID_4)), false); + } + + @Test + public void testModifyTwtWithWarning() throws Exception { + IdentifiableAttributes identifiableAttributes1 = getIdentifiableAttributes(TWT_ID_1, 1.); + IdentifiableAttributes identifiableAttributes2 = getIdentifiableAttributes(TWT_ID_2, 1.); + IdentifiableAttributes identifiableAttributes3 = getIdentifiableAttributes(TWT_ID_4, 1.); + IdentifiableAttributes identifiableAttributes4 = getIdentifiableAttributes(TWT_ID_6, 1.); + FilterEquipments filterTwt1 = getFilterEquipments(FILTER_ID_1, "filter1", List.of(identifiableAttributes1, identifiableAttributes2), List.of()); + FilterEquipments filterTwt2 = getFilterEquipments(FILTER_ID_4, "filter4", List.of(identifiableAttributes3, identifiableAttributes4), List.of()); + + UUID stubId = wireMockServer.stubFor(WireMock.get(WireMock.urlMatching(getPath(getNetworkUuid(), true) + ".{2,}")) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(List.of(filterTwt1, filterTwt2))) + .withHeader("Content-Type", "application/json"))).getId(); + + FormulaInfos formulaInfos = FormulaInfos.builder() + .filters(List.of(filter1, filter4)) + .fieldOrValue2(ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.RATIO_TAP_POSITION.name()).build()) + .fieldOrValue1(ReferenceFieldOrValue.builder().value(1.).build()) + .editedField(TwoWindingsTransformerField.RATIO_TAP_POSITION.name()) + .operator(Operator.ADDITION) + .build(); + + checkCreationApplicationStatus(ByFormulaModificationInfos.builder() + .identifiableType(getIdentifiableType()) + .formulaInfosList(List.of(formulaInfos)) + .build(), + NetworkModificationResult.ApplicationStatus.WITH_WARNINGS); + + assertNotNull(getNetwork().getTwoWindingsTransformer(TWT_ID_1).getRatioTapChanger()); + assertNotNull(getNetwork().getTwoWindingsTransformer(TWT_ID_2).getRatioTapChanger()); + assertEquals(2, getNetwork().getTwoWindingsTransformer(TWT_ID_1).getRatioTapChanger().getTapPosition()); + assertEquals(5, 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(getNetworkUuid(), 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, 110, + "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, 105, 115, + "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, 110, 120, + "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, 115, 125, + "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)); + + TwoWindingsTransformer twt5 = createTwoWindingsTransformer(s3, TWT_ID_5, TWT_ID_5, 50, 60, 70, 80, 30, 40, 120, 130, + "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, 125, 135, + "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() { + IdentifiableAttributes twt1 = getIdentifiableAttributes(TWT_ID_1, 1.0); + IdentifiableAttributes twt2 = getIdentifiableAttributes(TWT_ID_2, 2.0); + IdentifiableAttributes twt3 = getIdentifiableAttributes(TWT_ID_3, 2.0); + IdentifiableAttributes twt4 = getIdentifiableAttributes(TWT_ID_4, 5.0); + IdentifiableAttributes twt5 = getIdentifiableAttributes(TWT_ID_5, 6.0); + IdentifiableAttributes twt6 = getIdentifiableAttributes(TWT_ID_6, 7.0); + + FilterEquipments filter1 = getFilterEquipments(FILTER_ID_1, "filter1", List.of(twt1, twt2), List.of()); + FilterEquipments filter2 = getFilterEquipments(FILTER_ID_2, "filter2", List.of(twt1, twt3), List.of()); + FilterEquipments filter3 = getFilterEquipments(FILTER_ID_3, "filter3", List.of(twt4, twt5), List.of()); + FilterEquipments filter4 = getFilterEquipments(FILTER_ID_4, "filter4", List.of(twt4, twt6), List.of()); + + return List.of(filter1, filter2, filter3, filter4); + } + + @Override + protected List getFormulaInfos() { + FormulaInfos formulaInfos1 = getFormulaInfo(TwoWindingsTransformerField.TARGET_V.name(), + List.of(filter1), + Operator.PERCENTAGE, + ReferenceFieldOrValue.builder().value(200.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.TARGET_V.name()).build()); + + FormulaInfos formulaInfos2 = getFormulaInfo(TwoWindingsTransformerField.RATIO_TAP_POSITION.name(), + List.of(filter2), + Operator.MULTIPLICATION, + ReferenceFieldOrValue.builder().value(4.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.RATIO_TAP_POSITION.name()).build()); + + FormulaInfos formulaInfos3 = getFormulaInfo(TwoWindingsTransformerField.RATIO_LOW_TAP_POSITION.name(), + List.of(filter2), + Operator.ADDITION, + ReferenceFieldOrValue.builder().value(1.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.RATIO_LOW_TAP_POSITION.name()).build()); + + FormulaInfos formulaInfos4 = getFormulaInfo(TwoWindingsTransformerField.RATIO_TARGET_DEADBAND.name(), + List.of(filter1), + Operator.DIVISION, + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.RATIO_TARGET_DEADBAND.name()).build(), + ReferenceFieldOrValue.builder().value(5.).build()); + + FormulaInfos formulaInfos5 = getFormulaInfo(TwoWindingsTransformerField.REGULATION_VALUE.name(), + List.of(filter4), + Operator.PERCENTAGE, + ReferenceFieldOrValue.builder().value(200.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.REGULATION_VALUE.name()).build()); + + FormulaInfos formulaInfos6 = getFormulaInfo(TwoWindingsTransformerField.PHASE_TAP_POSITION.name(), + List.of(filter3), + Operator.MULTIPLICATION, + ReferenceFieldOrValue.builder().value(2.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.PHASE_TAP_POSITION.name()).build()); + + FormulaInfos formulaInfos7 = getFormulaInfo(TwoWindingsTransformerField.PHASE_LOW_TAP_POSITION.name(), + List.of(filter3), + Operator.MULTIPLICATION, + ReferenceFieldOrValue.builder().value(2.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.PHASE_LOW_TAP_POSITION.name()).build()); + + FormulaInfos formulaInfos8 = getFormulaInfo(TwoWindingsTransformerField.PHASE_TARGET_DEADBAND.name(), + List.of(filter4), + Operator.SUBTRACTION, + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.PHASE_TARGET_DEADBAND.name()).build(), + ReferenceFieldOrValue.builder().value(10.).build()); + + FormulaInfos formulaInfos9 = getFormulaInfo(TwoWindingsTransformerField.SERIES_REACTANCE.name(), + List.of(filter1, filter4), + Operator.ADDITION, + ReferenceFieldOrValue.builder().value(20.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.SERIES_REACTANCE.name()).build()); + + FormulaInfos formulaInfos10 = getFormulaInfo(TwoWindingsTransformerField.SERIES_RESISTANCE.name(), + List.of(filter2, filter3), + Operator.PERCENTAGE, + ReferenceFieldOrValue.builder().value(200.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.SERIES_RESISTANCE.name()).build()); + + FormulaInfos formulaInfos11 = getFormulaInfo(TwoWindingsTransformerField.MAGNETIZING_CONDUCTANCE.name(), + List.of(filter4, filter2), + Operator.ADDITION, + ReferenceFieldOrValue.builder().value(25.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.MAGNETIZING_CONDUCTANCE.name()).build()); + + FormulaInfos formulaInfos12 = getFormulaInfo(TwoWindingsTransformerField.MAGNETIZING_SUSCEPTANCE.name(), + List.of(filter1, filter3), + Operator.MULTIPLICATION, + ReferenceFieldOrValue.builder().value(2.5).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.MAGNETIZING_SUSCEPTANCE.name()).build()); + + FormulaInfos formulaInfos13 = getFormulaInfo(TwoWindingsTransformerField.RATED_VOLTAGE_1.name(), + List.of(filter2), + Operator.ADDITION, + ReferenceFieldOrValue.builder().value(15.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.RATED_VOLTAGE_1.name()).build()); + + FormulaInfos formulaInfos14 = getFormulaInfo(TwoWindingsTransformerField.RATED_VOLTAGE_2.name(), + List.of(filter3, filter2), + Operator.PERCENTAGE, + ReferenceFieldOrValue.builder().value(50.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.RATED_VOLTAGE_2.name()).build()); + + FormulaInfos formulaInfos15 = getFormulaInfo(TwoWindingsTransformerField.RATED_S.name(), + List.of(filter1, filter2), + Operator.PERCENTAGE, + ReferenceFieldOrValue.builder().value(200.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.RATED_S.name()).build()); + + return List.of(formulaInfos1, + formulaInfos2, + formulaInfos3, + formulaInfos4, + formulaInfos5, + formulaInfos6, + formulaInfos7, + formulaInfos8, + formulaInfos9, + formulaInfos10, + formulaInfos11, + formulaInfos12, + formulaInfos13, + formulaInfos14, + formulaInfos15); + } + + @Override + protected List getUpdatedFormulaInfos() { + FormulaInfos formulaInfos1 = getFormulaInfo(TwoWindingsTransformerField.TARGET_V.name(), + List.of(filter3), + Operator.PERCENTAGE, + ReferenceFieldOrValue.builder().value(200.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.TARGET_V.name()).build()); + + FormulaInfos formulaInfos2 = getFormulaInfo(TwoWindingsTransformerField.RATIO_TAP_POSITION.name(), + List.of(filter2), + Operator.MULTIPLICATION, + ReferenceFieldOrValue.builder().value(3.5).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.RATIO_TAP_POSITION.name()).build()); + + FormulaInfos formulaInfos3 = getFormulaInfo(TwoWindingsTransformerField.RATIO_LOW_TAP_POSITION.name(), + List.of(filter1), + Operator.MULTIPLICATION, + ReferenceFieldOrValue.builder().value(3.).build(), + ReferenceFieldOrValue.builder().equipmentField(TwoWindingsTransformerField.RATIO_LOW_TAP_POSITION.name()).build()); + + return List.of(formulaInfos1, + formulaInfos2, + formulaInfos3); + } + + @Override + protected IdentifiableType getIdentifiableType() { + return IdentifiableType.TWO_WINDINGS_TRANSFORMER; + } + + @Override + protected void assertAfterNetworkModificationCreation() { + TwoWindingsTransformer twt1 = getNetwork().getTwoWindingsTransformer(TWT_ID_1); + RatioTapChanger ratioTapChanger1 = twt1.getRatioTapChanger(); + assertNotNull(ratioTapChanger1); + assertEquals(100, ratioTapChanger1.getTargetV(), 0); + assertEquals(1, ratioTapChanger1.getLowTapPosition()); + assertEquals(4, ratioTapChanger1.getTapPosition()); + assertEquals(11, ratioTapChanger1.getTargetDeadband(), 0); + assertEquals(60, twt1.getX(), 0); + assertEquals(150, twt1.getB(), 0); + assertEquals(60, twt1.getR(), 0); + assertEquals(75, twt1.getG(), 0); + assertEquals(25, twt1.getRatedU1(), 0); + assertEquals(10, twt1.getRatedU2(), 0); + assertEquals(44, twt1.getRatedS(), 0); + + TwoWindingsTransformer twt2 = getNetwork().getTwoWindingsTransformer(TWT_ID_2); + RatioTapChanger ratioTapChanger2 = twt2.getRatioTapChanger(); + assertNotNull(ratioTapChanger2); + assertEquals(106, ratioTapChanger2.getTargetV(), 0); + assertEquals(3, ratioTapChanger2.getLowTapPosition()); + assertEquals(4, ratioTapChanger2.getTapPosition()); + assertEquals(11.6, ratioTapChanger2.getTargetDeadband(), 0); + assertEquals(65, twt2.getX(), 0); + assertEquals(162.5, twt2.getB(), 0); + assertEquals(15, twt2.getRatedU1(), 0); + assertEquals(20, twt2.getRatedS(), 0); + + TwoWindingsTransformer twt3 = getNetwork().getTwoWindingsTransformer(TWT_ID_3); + RatioTapChanger ratioTapChanger3 = twt3.getRatioTapChanger(); + assertNotNull(ratioTapChanger3); + assertEquals(1, ratioTapChanger3.getLowTapPosition()); + assertEquals(4, ratioTapChanger3.getTapPosition()); + assertEquals(80, twt3.getR(), 0); + assertEquals(85, twt3.getG(), 0); + assertEquals(35, twt3.getRatedU1(), 0); + assertEquals(15, twt3.getRatedU2(), 0); + assertEquals(50, twt3.getRatedS(), 0); + + TwoWindingsTransformer twt4 = getNetwork().getTwoWindingsTransformer(TWT_ID_4); + PhaseTapChanger phaseTapChanger4 = twt4.getPhaseTapChanger(); + assertNotNull(phaseTapChanger4); + assertEquals(90, phaseTapChanger4.getRegulationValue(), 0); + assertEquals(2, phaseTapChanger4.getLowTapPosition()); + assertEquals(4, phaseTapChanger4.getTapPosition()); + assertEquals(24, phaseTapChanger4.getTargetDeadband(), 0); + assertEquals(90, twt4.getR(), 0); + assertEquals(75, twt4.getX(), 0); + assertEquals(90, twt4.getG(), 0); + assertEquals(187.5, twt4.getB(), 0); + assertEquals(25, twt4.getRatedU1(), 0); + assertEquals(17.5, twt4.getRatedU2(), 0); + assertEquals(15, twt4.getRatedS(), 0); + + TwoWindingsTransformer twt5 = getNetwork().getTwoWindingsTransformer(TWT_ID_5); + PhaseTapChanger phaseTapChanger5 = twt5.getPhaseTapChanger(); + assertNotNull(phaseTapChanger4); + assertEquals(4, phaseTapChanger5.getLowTapPosition()); + assertEquals(4, phaseTapChanger5.getTapPosition()); + assertEquals(100, twt5.getR(), 0); + assertEquals(200, twt5.getB(), 0); + assertEquals(20, twt5.getRatedU2(), 0); + + TwoWindingsTransformer twt6 = getNetwork().getTwoWindingsTransformer(TWT_ID_6); + PhaseTapChanger phaseTapChanger6 = twt6.getPhaseTapChanger(); + assertNotNull(phaseTapChanger4); + assertEquals(94, phaseTapChanger6.getRegulationValue(), 0); + assertEquals(26, phaseTapChanger6.getTargetDeadband(), 0); + assertEquals(85, twt6.getX(), 0); + assertEquals(100, 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(); + } +}