Skip to content

Commit 1f3e29f

Browse files
authored
Add limits properties infos to operational limits groups (#105)
Signed-off-by: basseche <[email protected]>
1 parent 4635d11 commit 1f3e29f

File tree

8 files changed

+171
-25
lines changed

8 files changed

+171
-25
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Copyright (c) 2025, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
8+
package org.gridsuite.modification.dto;
9+
10+
/**
11+
* @author El Cheikh Bassel <bassel.el-cheikh_externe at rte-france.com>
12+
*/
13+
14+
public record LimitsPropertyInfos(String name, String value) {
15+
}

src/main/java/org/gridsuite/modification/dto/OperationalLimitsGroupInfos.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
*/
77
package org.gridsuite.modification.dto;
88

9+
import com.fasterxml.jackson.annotation.JsonInclude;
910
import io.swagger.v3.oas.annotations.media.Schema;
1011
import lombok.Getter;
1112
import lombok.NoArgsConstructor;
1213
import lombok.Setter;
1314
import lombok.ToString;
1415
import lombok.experimental.SuperBuilder;
1516

17+
import java.util.List;
18+
1619
@SuperBuilder
1720
@NoArgsConstructor
1821
@Getter
@@ -29,6 +32,10 @@ public class OperationalLimitsGroupInfos {
2932
@Schema(description = "application side")
3033
private Applicability applicability;
3134

35+
@Schema(description = "limits properties")
36+
@JsonInclude(JsonInclude.Include.NON_NULL)
37+
private List<LimitsPropertyInfos> limitsProperties;
38+
3239
public enum Applicability {
3340
EQUIPMENT, // SIDE1 + SIDE2
3441
SIDE1,

src/main/java/org/gridsuite/modification/modifications/AbstractBranchModification.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131
public abstract class AbstractBranchModification extends AbstractModification {
3232

3333
private static final String DURATION = "duration";
34-
private static final String NAME = "name";
35-
private static final String VALUE = "value";
34+
public static final String NAME = "name";
35+
public static final String VALUE = "value";
3636
private static final String VALIDITY = "validity";
3737
private static final String LIMIT_ACCEPTABLE_DURATION = "limitAcceptableDuration";
38-
private static final String OPERATIONAL_LIMITS_GROUP_NAME = "operationalLimitsGroupName";
38+
public static final String OPERATIONAL_LIMITS_GROUP_NAME = "operationalLimitsGroupName";
3939
private static final String SIDE = "side";
4040
private static final String APPLICABILITY = "applicability";
4141

src/main/java/org/gridsuite/modification/modifications/LineCreation.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ public void check(Network network) throws NetworkModificationException {
5252
checkIsNotNegativeValue(errorMessage, modificationInfos.getG2(), CREATE_LINE_ERROR, "Conductance on side 2 G2");
5353
}
5454

55+
private ReportNode addLimitSetReportNode(ReportNode limitsReporter) {
56+
return limitsReporter.newReportNode()
57+
.withSeverity(TypedValue.INFO_SEVERITY)
58+
.withMessageTemplate("network.modification.LimitSets")
59+
.add();
60+
}
61+
5562
@Override
5663
public void apply(Network network, ReportNode subReportNode) {
5764
VoltageLevel voltageLevel1 = ModificationUtils.getInstance().getVoltageLevel(network, modificationInfos.getVoltageLevelId1());
@@ -72,11 +79,16 @@ public void apply(Network network, ReportNode subReportNode) {
7279
ReportNode limitsReporter = subReportNode.newReportNode().withMessageTemplate("network.modification.limitsCreated").add();
7380
List<OperationalLimitsGroupInfos> opLimitsGroupSide1 = ModificationUtils.getOperationalLimitsGroupsOnSide(modificationInfos.getOperationalLimitsGroups(), Applicability.SIDE1);
7481
List<OperationalLimitsGroupInfos> opLimitsGroupSide2 = ModificationUtils.getOperationalLimitsGroupsOnSide(modificationInfos.getOperationalLimitsGroups(), Applicability.SIDE2);
82+
ReportNode reportNode = null;
7583
if (!CollectionUtils.isEmpty(opLimitsGroupSide1)) {
76-
ModificationUtils.getInstance().setCurrentLimitsOnASide(opLimitsGroupSide1, line, ONE, limitsReporter);
84+
reportNode = addLimitSetReportNode(limitsReporter);
85+
ModificationUtils.getInstance().setCurrentLimitsOnASide(reportNode, opLimitsGroupSide1, line, ONE);
7786
}
7887
if (!CollectionUtils.isEmpty(opLimitsGroupSide2)) {
79-
ModificationUtils.getInstance().setCurrentLimitsOnASide(opLimitsGroupSide2, line, TWO, limitsReporter);
88+
if (reportNode == null) {
89+
reportNode = addLimitSetReportNode(limitsReporter);
90+
}
91+
ModificationUtils.getInstance().setCurrentLimitsOnASide(reportNode, opLimitsGroupSide2, line, TWO);
8092
}
8193
List<ReportNode> limitSetsOnSideReportNodes = new ArrayList<>();
8294
if (modificationInfos.getSelectedOperationalLimitsGroup1() != null) {

src/main/java/org/gridsuite/modification/modifications/TwoWindingsTransformerCreation.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,10 @@ private void create2WTInOtherBreaker(Network network, VoltageLevel voltageLevel1
239239
completeTwoWindingsTransformerCreation(network, twoWindingsTransformer, modificationInfos, subReportNode);
240240
}
241241

242-
private void setCurrentLimitsForSide(List<OperationalLimitsGroupInfos> operationalLimitsGroups, String selectedGroup, TwoWindingsTransformer transformer, TwoSides side, ReportNode limitsReporter,
242+
private void setCurrentLimitsForSide(ReportNode reportNode, List<OperationalLimitsGroupInfos> operationalLimitsGroups, String selectedGroup, TwoWindingsTransformer transformer, TwoSides side,
243243
List<ReportNode> limitSetsOnSideReportNodes) {
244244
if (!CollectionUtils.isEmpty(operationalLimitsGroups)) {
245-
getInstance().setCurrentLimitsOnASide(operationalLimitsGroups, transformer, side, limitsReporter);
245+
getInstance().setCurrentLimitsOnASide(reportNode, operationalLimitsGroups, transformer, side);
246246
}
247247
if (selectedGroup != null) {
248248
if (!ModificationUtils.hasLimitSet(operationalLimitsGroups, selectedGroup)) {
@@ -290,8 +290,12 @@ private void completeTwoWindingsTransformerCreation(Network network,
290290
List<OperationalLimitsGroupInfos> operationalLimitsGroups2 = ModificationUtils.getOperationalLimitsGroupsOnSide(modificationInfos.getOperationalLimitsGroups(), SIDE2);
291291

292292
List<ReportNode> limitSetsOnSideReportNodes = new ArrayList<>();
293-
setCurrentLimitsForSide(operationalLimitsGroups1, modificationInfos.getSelectedOperationalLimitsGroup1(), twoWindingsTransformer, TwoSides.ONE, limitsReporter, limitSetsOnSideReportNodes);
294-
setCurrentLimitsForSide(operationalLimitsGroups2, modificationInfos.getSelectedOperationalLimitsGroup2(), twoWindingsTransformer, TwoSides.TWO, limitsReporter, limitSetsOnSideReportNodes);
293+
ReportNode reportNode = limitsReporter.newReportNode()
294+
.withSeverity(TypedValue.INFO_SEVERITY)
295+
.withMessageTemplate("network.modification.LimitSets")
296+
.add();
297+
setCurrentLimitsForSide(reportNode, operationalLimitsGroups1, modificationInfos.getSelectedOperationalLimitsGroup1(), twoWindingsTransformer, TwoSides.ONE, limitSetsOnSideReportNodes);
298+
setCurrentLimitsForSide(reportNode, operationalLimitsGroups2, modificationInfos.getSelectedOperationalLimitsGroup2(), twoWindingsTransformer, TwoSides.TWO, limitSetsOnSideReportNodes);
295299
if (!limitSetsOnSideReportNodes.isEmpty()) {
296300
ModificationUtils.getInstance().reportModifications(limitsReporter, limitSetsOnSideReportNodes,
297301
"network.modification.ActiveLimitSets");

src/main/java/org/gridsuite/modification/utils/ModificationUtils.java

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
import static com.powsybl.iidm.network.TwoSides.ONE;
3535
import static org.gridsuite.modification.NetworkModificationException.Type.*;
36+
import static org.gridsuite.modification.modifications.AbstractBranchModification.*;
3637

3738
/**
3839
* @author Slimane Amar <slimane.amar at rte-france.com>
@@ -549,6 +550,20 @@ public ReportNode reportModifications(ReportNode reportNode, List<ReportNode> re
549550
return reportModifications(reportNode, reports, subReportNodeKey, Map.of());
550551
}
551552

553+
public void reportModifications(ReportNode reportNode, List<ReportNode> reports) {
554+
List<ReportNode> validReports = reports.stream().filter(Objects::nonNull).toList();
555+
if (!validReports.isEmpty() && reportNode != null) {
556+
for (ReportNode report : validReports) {
557+
ReportNodeAdder reportNodeAdder = reportNode.newReportNode().withMessageTemplate(report.getMessageKey()).withSeverity(TypedValue.DETAIL_SEVERITY);
558+
for (Map.Entry<String, TypedValue> valueEntry : report.getValues().entrySet()) {
559+
reportNodeAdder.withUntypedValue(valueEntry.getKey(), valueEntry.getValue().toString());
560+
}
561+
report.getValue(ReportConstants.SEVERITY_KEY).ifPresent(reportNodeAdder::withSeverity);
562+
reportNodeAdder.add();
563+
}
564+
}
565+
}
566+
552567
public ReportNode reportModifications(ReportNode reportNode, List<ReportNode> reports, String subReportNodeKey, Map<String, Object> subReportNodeKeyArgs) {
553568
List<ReportNode> validReports = reports.stream().filter(Objects::nonNull).toList();
554569
ReportNode subReportNode = null;
@@ -1064,33 +1079,36 @@ public Identifiable<?> getEquipmentByIdentifiableType(Network network, Identifia
10641079
}
10651080

10661081
/**
1082+
* @param reportNode Limit sets report node
10671083
* @param opLimitGroups added current limits
10681084
* @param branch branch to which limits are going to be added
10691085
* @param side which side of the branch receives the limits
1070-
* @param limitsReporter reporter limits on side
10711086
*/
1072-
public void setCurrentLimitsOnASide(List<OperationalLimitsGroupInfos> opLimitGroups, Branch<?> branch, TwoSides side, ReportNode limitsReporter) {
1073-
List<ReportNode> limitSetsOnSideReportNodes = new ArrayList<>();
1087+
public void setCurrentLimitsOnASide(ReportNode reportNode, List<OperationalLimitsGroupInfos> opLimitGroups, Branch<?> branch, TwoSides side) {
1088+
1089+
if (CollectionUtils.isEmpty(opLimitGroups)) {
1090+
return;
1091+
}
1092+
10741093
for (OperationalLimitsGroupInfos opLimitsGroup : opLimitGroups) {
10751094
boolean hasPermanent = opLimitsGroup.getCurrentLimits().getPermanentLimit() != null;
10761095
boolean hasTemporary = !CollectionUtils.isEmpty(opLimitsGroup.getCurrentLimits().getTemporaryLimits());
10771096
boolean hasLimits = hasPermanent || hasTemporary;
10781097

1079-
if (!hasLimits) {
1098+
if (!hasLimits || opLimitsGroup.getId() == null) {
10801099
continue;
10811100
}
10821101

10831102
OperationalLimitsGroup opGroup = side == ONE
10841103
? branch.newOperationalLimitsGroup1(opLimitsGroup.getId())
10851104
: branch.newOperationalLimitsGroup2(opLimitsGroup.getId());
1086-
if (opLimitsGroup.getId() != null) {
1087-
limitSetsOnSideReportNodes.add(ReportNode.newRootReportNode()
1088-
.withAllResourceBundlesFromClasspath()
1089-
.withMessageTemplate("network.modification.limitSetAdded")
1090-
.withUntypedValue("name", opLimitsGroup.getId())
1091-
.withSeverity(TypedValue.INFO_SEVERITY)
1092-
.build());
1093-
}
1105+
1106+
ReportNode limitSetNode = reportNode.newReportNode()
1107+
.withMessageTemplate("network.modification.limitSetAdded")
1108+
.withUntypedValue("name", opLimitsGroup.getId())
1109+
.withSeverity(TypedValue.INFO_SEVERITY)
1110+
.add();
1111+
10941112
CurrentLimitsAdder limitsAdder = opGroup.newCurrentLimits();
10951113
if (hasPermanent) {
10961114
limitsAdder.setPermanentLimit(opLimitsGroup.getCurrentLimits().getPermanentLimit());
@@ -1108,11 +1126,41 @@ public void setCurrentLimitsOnASide(List<OperationalLimitsGroupInfos> opLimitGro
11081126
});
11091127
}
11101128
limitsAdder.add();
1129+
1130+
//add properties
1131+
List<ReportNode> detailsOnLimitSet = new ArrayList<>();
1132+
if (!CollectionUtils.isEmpty(opLimitsGroup.getLimitsProperties()) &&
1133+
checkPropertiesUnicity(opLimitsGroup.getLimitsProperties(), detailsOnLimitSet)) {
1134+
opLimitsGroup.getLimitsProperties().forEach(property -> {
1135+
detailsOnLimitSet.add(
1136+
ReportNode.newRootReportNode().withSeverity(TypedValue.DETAIL_SEVERITY)
1137+
.withMessageTemplate("network.modification.propertyAdded")
1138+
.withUntypedValue(NAME, property.name())
1139+
.withUntypedValue(VALUE, property.value()).build());
1140+
opGroup.setProperty(property.name(), property.value());
1141+
});
1142+
if (!detailsOnLimitSet.isEmpty()) {
1143+
ModificationUtils.getInstance().reportModifications(limitSetNode, detailsOnLimitSet);
1144+
}
1145+
}
1146+
}
1147+
}
1148+
1149+
private static boolean checkPropertiesUnicity(List<LimitsPropertyInfos> properties, List<ReportNode> reportNodeList) {
1150+
1151+
if (CollectionUtils.isEmpty(properties)) {
1152+
return true;
11111153
}
1112-
if (!limitSetsOnSideReportNodes.isEmpty()) {
1113-
ModificationUtils.getInstance().reportModifications(limitsReporter, limitSetsOnSideReportNodes,
1114-
"network.modification.LimitsSetsOnSide" + side.getNum());
1154+
boolean unicity = true;
1155+
for (LimitsPropertyInfos property : properties) {
1156+
if (properties.stream().filter(prop -> prop.name().equals(property.name())).toList().size() > 1) {
1157+
reportNodeList.add(ReportNode.newRootReportNode().withSeverity(TypedValue.ERROR_SEVERITY)
1158+
.withMessageTemplate("network.modification.propertyNameUnique")
1159+
.withUntypedValue(NAME, property.name()).build());
1160+
unicity = false;
1161+
}
11151162
}
1163+
return unicity;
11161164
}
11171165

11181166
public <T> ReportNode buildCreationReport(T value, String fieldName) {

src/main/resources/org/gridsuite/modification/reports.properties

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ network.modification.LimitsAndSetpointsCreated = Limits and Setpoints
2727
network.modification.LimitsSetsOnSide1 = Limit Sets Side 1
2828
network.modification.LimitsSetsOnSide2 = Limit Sets Side 2
2929
network.modification.ActiveLimitSets= Active limit sets
30+
network.modification.LimitSets= Limit sets
3031
network.modification.LineProperties = Properties
3132
network.modification.LoadProperties = Properties
3233
network.modification.MaxUsedMarginalCost = Marginal cost: ${maxUsedMarginalCost}
@@ -174,7 +175,7 @@ network.modification.invalidFilters = ${errorType}: There is no valid equipment
174175
network.modification.lcc.creation = Lcc creation ${lccId}
175176
network.modification.lccCharacteristics = Characteristics
176177
network.modification.lccCreated = New lcc with id=${id} created
177-
network.modification.limitSetAdded = ${name} added
178+
network.modification.limitSetAdded = Limit set ${name} added
178179
network.modification.operationalLimitsGroupAdded = New operational limits group added named ${operationalLimitsGroupName} on ${side}
179180
network.modification.operationalLimitsGroupReplaced = Operational limits group named ${operationalLimitsGroupName} has been replaced on ${side}
180181
network.modification.operationalLimitsGroupModified = Operational limits group named ${operationalLimitsGroupName} has been modified on ${side}
@@ -228,6 +229,7 @@ network.modification.phaseTapPositionChanged = 2WT with id=${id} phase tap chang
228229
network.modification.propertyAdded = Property ${name} added with value ${value}
229230
network.modification.propertyChanged = Property ${name} changed : ${from} -> ${to}
230231
network.modification.propertyDeleted = Property ${name} deleted
232+
network.modification.propertyNameUnique = Property ${name} should be unique
231233
network.modification.ratioTapChanger1.tapPosition = 3WT with id=${id} ratio tap changer 1 position changed
232234
network.modification.ratioTapChanger2.tapPosition = 3WT with id=${id} ratio tap changer 2 position changed
233235
network.modification.ratioTapChanger3.tapPosition = 3WT with id=${id} ratio tap changer 3 position changed
@@ -336,5 +338,6 @@ network.modification.lcc.shuntCompensator.notFound = Shunt compensator id=${id}
336338
network.modification.lcc.shuntCompensator.removed = Shunt compensator id=${id} removed
337339
network.modification.lcc.shuntCompensator.connected = Equipment with id=${id} is connected
338340
network.modification.lcc.shuntCompensator.disconnected = Equipment with id=${id} is disconnected
341+
network.modification.operationalLimitsGroup.creation = Creation of ${operationalLimitsGroupName}
339342
network.modification.operationalLimitsGroupPropertyValueNotFoundError = Cannot modify equipment ${id} : missing limit set applicable on side ${side} with property named ${propertyName} and with value ${propertyValue} : equipment ignored
340343
network.modification.operationalLimitsGroupPropertyValueMultipleError = Cannot modify equipment ${id} : multiple limit sets applicable on side ${side} with property named ${propertyName} and with value ${propertyValue} : equipment ignored

0 commit comments

Comments
 (0)