Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ public enum OperationalLimitsGroupModificationType {
REPLACE,
// Modification type for simple form modifications :
MODIFY_OR_ADD, // if the OLG exists it is modified, if not it is created
DELETE,
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,15 @@ private void detectApplicabilityChange(Branch<?> branch, List<OperationalLimitsG
if (limitsGroup1 == null && modifiedLimitSetInfos.getApplicability().equals(SIDE2)
|| limitsGroup2 == null && modifiedLimitSetInfos.getApplicability().equals(SIDE1)) {
return;
} else if (limitsGroup1 != null && limitsGroup2 != null && (modifiedLimitSetInfos.getApplicability().equals(SIDE1)
|| modifiedLimitSetInfos.getApplicability().equals(SIDE2))) {
} else if (limitsGroup1 != null && limitsGroup2 != null && !modifiedLimitSetInfos.getApplicability().equals(EQUIPMENT)) {
// applicability change from EQUIPMENT to one side
if (shouldDeletedOtherSide(branch, modificationInfos, modifiedLimitSetInfos)) {
if (modifiedLimitSetInfos.getApplicability().equals(SIDE1)) {
branch.removeOperationalLimitsGroup2(modifiedLimitSetInfos.getId());
} else {
logApplicabilityChange(olgReports, limitsGroup1.getId(), SIDE1);
} else if (modifiedLimitSetInfos.getApplicability().equals(SIDE2)) {
branch.removeOperationalLimitsGroup1(modifiedLimitSetInfos.getId());
logApplicabilityChange(olgReports, limitsGroup2.getId(), SIDE2);
}
}
return;
Expand All @@ -180,16 +182,20 @@ private void detectApplicabilityChange(Branch<?> branch, List<OperationalLimitsG
applicabilityChanged = true;
}
if (applicabilityChanged) {
olgReports.add(ReportNode.newRootReportNode().withMessageTemplate("network.modification.applicabilityChanged")
.withUntypedValue(OPERATIONAL_LIMITS_GROUP_NAME, limitsGroup1.getId())
.withUntypedValue(APPLICABILITY, EQUIPMENT.toString())
.withSeverity(TypedValue.INFO_SEVERITY)
.build());
logApplicabilityChange(olgReports, limitsGroup1.getId(), EQUIPMENT);
}
}
}
}

private void logApplicabilityChange(List<ReportNode> olgReports, String groupId, OperationalLimitsGroupInfos.Applicability applicability) {
olgReports.add(ReportNode.newRootReportNode().withMessageTemplate("network.modification.applicabilityChanged")
.withUntypedValue(OPERATIONAL_LIMITS_GROUP_NAME, groupId)
.withUntypedValue(APPLICABILITY, applicability.toString())
.withSeverity(TypedValue.INFO_SEVERITY)
.build());
}

private void modifyOperationalLimitsGroups(Branch<?> branch, List<OperationalLimitsGroupModificationInfos> operationalLimitsInfos, List<ReportNode> olgReports) {
for (OperationalLimitsGroupModificationInfos opLGModifInfos : operationalLimitsInfos) {
if (opLGModifInfos.getModificationType() == null) {
Expand All @@ -204,12 +210,12 @@ private void modifyOperationalLimitsGroups(Branch<?> branch, List<OperationalLim
if (applicability == SIDE1
|| applicability == EQUIPMENT) {
OperationalLimitsGroup operationalLimitsGroup1 = branch.getOperationalLimitsGroup1(opLGModifInfos.getId()).orElse(null);
applyModificationToOperationalLimitsGroup(branch::newOperationalLimitsGroup1, opLGModifInfos, operationalLimitsGroup1, olgReports, SIDE1);
applyModificationToOperationalLimitsGroup(branch, branch::newOperationalLimitsGroup1, opLGModifInfos, operationalLimitsGroup1, olgReports, SIDE1);
}
if (applicability == SIDE2
|| applicability == EQUIPMENT) {
OperationalLimitsGroup operationalLimitsGroup2 = branch.getOperationalLimitsGroup2(opLGModifInfos.getId()).orElse(null);
applyModificationToOperationalLimitsGroup(branch::newOperationalLimitsGroup2, opLGModifInfos, operationalLimitsGroup2, olgReports, SIDE2);
applyModificationToOperationalLimitsGroup(branch, branch::newOperationalLimitsGroup2, opLGModifInfos, operationalLimitsGroup2, olgReports, SIDE2);
}
}
}
Expand Down Expand Up @@ -408,6 +414,7 @@ private boolean updateConnection(Branch<?> branch, TwoSides side, Boolean connec
* therefore applicability is SIDE1 or SIDE2, not EQUIPMENT
*/
protected void applyModificationToOperationalLimitsGroup(
Branch<?> branch,
Function<String, OperationalLimitsGroup> groupFactory,
OperationalLimitsGroupModificationInfos opLGModificationInfos,
OperationalLimitsGroup modifiedOperationalLimitsGroup,
Expand All @@ -434,9 +441,30 @@ protected void applyModificationToOperationalLimitsGroup(
case OperationalLimitsGroupModificationType.REPLACE: {
replaceOpLG(groupFactory, opLGModificationInfos, modifiedOperationalLimitsGroup, operationalLimitsGroupReports, applicability);
} break;
case OperationalLimitsGroupModificationType.DELETE: {
removeOlg(branch, opLGModificationInfos, operationalLimitsGroupReports, applicability);
}
}
}

private void removeOlg(Branch<?> branch, OperationalLimitsGroupModificationInfos opLGModificationInfos, List<ReportNode> operationalLimitsGroupReports, OperationalLimitsGroupInfos.Applicability applicability) {
if (applicability == SIDE1 && branch.getOperationalLimitsGroup1(opLGModificationInfos.getId()).isEmpty() ||
applicability == SIDE2 && branch.getOperationalLimitsGroup2(opLGModificationInfos.getId()).isEmpty()) {
throw new PowsyblException("Cannot delete operational limit group " + opLGModificationInfos.getId() + " which has not been found in equipment on side " + applicability);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you sur we should throw here ? Why not just log an error ?

}
if (applicability == SIDE1) {
branch.removeOperationalLimitsGroup1(opLGModificationInfos.getId());
} else if (applicability == SIDE2) {
branch.removeOperationalLimitsGroup2(opLGModificationInfos.getId());
}
operationalLimitsGroupReports.add(ReportNode.newRootReportNode()
.withMessageTemplate("network.modification.operationalLimitsGroupDeleted")
.withUntypedValue(OPERATIONAL_LIMITS_GROUP_NAME, opLGModificationInfos.getId())
.withUntypedValue(SIDE, applicability.toString())
.withSeverity(TypedValue.INFO_SEVERITY)
.build());
}

private void replaceOpLG(Function<String, OperationalLimitsGroup> groupFactory, OperationalLimitsGroupModificationInfos opLGModificationInfos, OperationalLimitsGroup modifiedOperationalLimitsGroup, List<ReportNode> operationalLimitsGroupReports, OperationalLimitsGroupInfos.Applicability applicability) {
if (modifiedOperationalLimitsGroup != null) {
modifiedOperationalLimitsGroup.removeCurrentLimits();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ network.modification.limitSetAdded = ${name} added
network.modification.operationalLimitsGroupAdded = New operational limits group added named ${operationalLimitsGroupName} on ${side}
network.modification.operationalLimitsGroupReplaced = Operational limits group named ${operationalLimitsGroupName} has been replaced on ${side}
network.modification.operationalLimitsGroupModified = Operational limits group named ${operationalLimitsGroupName} has been modified on ${side}
network.modification.operationalLimitsGroupDeleted = Operational limits group named ${operationalLimitsGroupName} has been deleted on ${side}
network.modification.limitSetSelectedOnSide1 = limit set selected on side 1 : ${selectedOperationalLimitsGroup1}
network.modification.limitSetSelectedOnSide2 = limit set selected on side 2 : ${selectedOperationalLimitsGroup2}
network.modification.noLimitSetSelectedOnSide1 = No limit set selected on side 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package org.gridsuite.modification.modifications;

import com.fasterxml.jackson.core.type.TypeReference;
import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.ConnectablePosition;
import com.powsybl.iidm.network.extensions.Measurement;
Expand All @@ -23,6 +24,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.gridsuite.modification.NetworkModificationException.Type.LINE_NOT_FOUND;
import static org.gridsuite.modification.dto.OperationalLimitsGroupInfos.Applicability.*;
import static org.gridsuite.modification.dto.OperationalLimitsGroupModificationType.DELETE;
import static org.gridsuite.modification.dto.OperationalLimitsGroupModificationType.MODIFY_OR_ADD;
import static org.junit.jupiter.api.Assertions.*;

Expand Down Expand Up @@ -325,6 +327,79 @@ void testConnectWhenNoSwitchesOpened() {
assertEquals("BRANCH_MODIFICATION_ERROR : Could not connect equipment 'line1' on side 1 & 2", exception.getMessage());
}

@Test
void testDelete() {
Line line = getNetwork().getLine("line1");
// side 1
line.newOperationalLimitsGroup1("NewLimitsGroup1").newCurrentLimits()
.setPermanentLimit(10.0)
.add();
line.newOperationalLimitsGroup1("NewLimitsGroup2").newCurrentLimits()
.setPermanentLimit(10.0)
.add();
// side 2
line.newOperationalLimitsGroup2("NewLimitsGroup1").newCurrentLimits()
.setPermanentLimit(10.0)
.add();
line.newOperationalLimitsGroup2("NewLimitsGroup3").newCurrentLimits()
.setPermanentLimit(10.0)
.add();
Comment on lines +346 to +355
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for "NewLimitsGroup2" and "NewLimitsGroup3" to have 2 different names ? Wouldn't it be more useful to have the same name in order to check that the DELETE correctly handle the applicability and doesn't delete both ?


// modification 1 remove olg on both side
OperationalLimitsGroupModificationInfos opLimitsGroupInfos1 = OperationalLimitsGroupModificationInfos.builder()
.id("NewLimitsGroup1").applicability(EQUIPMENT).modificationType(DELETE).build();
LineModificationInfos lineModificationInfos1 = LineModificationInfos.builder()
.enableOLGModification(true)
.equipmentId("line1")
.operationalLimitsGroups(Collections.singletonList(opLimitsGroupInfos1)).build();
lineModificationInfos1.toModification().apply(getNetwork());

assertTrue(line.getOperationalLimitsGroup1("NewLimitsGroup1").isEmpty());
assertTrue(line.getOperationalLimitsGroup2("NewLimitsGroup1").isEmpty());
assertTrue(line.getOperationalLimitsGroup1("NewLimitsGroup2").isPresent());
assertTrue(line.getOperationalLimitsGroup2("NewLimitsGroup3").isPresent());

// modification 2 remove olg on side one
OperationalLimitsGroupModificationInfos opLimitsGroupInfos2 = OperationalLimitsGroupModificationInfos.builder()
.id("NewLimitsGroup2").applicability(SIDE1).modificationType(DELETE).build();
LineModificationInfos lineModificationInfos2 = LineModificationInfos.builder()
.enableOLGModification(true)
.equipmentId("line1")
.operationalLimitsGroups(Collections.singletonList(opLimitsGroupInfos2)).build();
lineModificationInfos2.toModification().apply(getNetwork());

assertTrue(line.getOperationalLimitsGroup1("NewLimitsGroup1").isEmpty());
assertTrue(line.getOperationalLimitsGroup2("NewLimitsGroup1").isEmpty());
assertTrue(line.getOperationalLimitsGroup1("NewLimitsGroup2").isEmpty());
assertTrue(line.getOperationalLimitsGroup2("NewLimitsGroup3").isPresent());

// modification 3 remove olg on side two
OperationalLimitsGroupModificationInfos opLimitsGroupInfos3 = OperationalLimitsGroupModificationInfos.builder()
.id("NewLimitsGroup3").applicability(SIDE2).modificationType(DELETE).build();
LineModificationInfos lineModificationInfos3 = LineModificationInfos.builder()
.enableOLGModification(true)
.equipmentId("line1")
.operationalLimitsGroups(Collections.singletonList(opLimitsGroupInfos3)).build();
lineModificationInfos3.toModification().apply(getNetwork());

assertTrue(line.getOperationalLimitsGroup1("NewLimitsGroup1").isEmpty());
assertTrue(line.getOperationalLimitsGroup2("NewLimitsGroup1").isEmpty());
assertTrue(line.getOperationalLimitsGroup1("NewLimitsGroup2").isEmpty());
assertTrue(line.getOperationalLimitsGroup2("NewLimitsGroup3").isEmpty());

// try to remove not existing group
OperationalLimitsGroupModificationInfos opLimitsGroupInfos4 = OperationalLimitsGroupModificationInfos.builder()
.id("doesNotExist").applicability(SIDE2).modificationType(DELETE).build();
LineModificationInfos lineModificationInfos4 = LineModificationInfos.builder()
.enableOLGModification(true)
.equipmentId("line1")
.operationalLimitsGroups(Collections.singletonList(opLimitsGroupInfos4)).build();
Network network = getNetwork();
AbstractModification modification = lineModificationInfos4.toModification();
String errorMessage = assertThrows(PowsyblException.class, () -> modification.apply(network)).getMessage();
assertEquals("Cannot delete operational limit group doesNotExist which has not been found in equipment on side SIDE2", errorMessage);
}

private void changeLineConnectionState(Line existingEquipment, boolean expectedState) {
LineModificationInfos modificationInfos = (LineModificationInfos) buildModification();
modificationInfos.setTerminal1Connected(new AttributeModification<>(expectedState, OperationType.SET));
Expand Down