Skip to content

Commit e588129

Browse files
Generation dispatch logs on filters not found (#117)
* Log missing filters generation dispatch application Signed-off-by: Franck LECUYER <[email protected]>
1 parent 3fee94d commit e588129

File tree

3 files changed

+129
-12
lines changed

3 files changed

+129
-12
lines changed

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import lombok.Builder;
1717
import lombok.Getter;
1818

19+
import org.gridsuite.filter.AbstractFilter;
1920
import org.gridsuite.modification.IFilterService;
2021
import org.gridsuite.modification.ILoadFlowService;
2122
import org.gridsuite.modification.NetworkModificationException;
@@ -450,8 +451,36 @@ private void reportDisconnectedGenerators(List<Generator> globalDisconnectedGene
450451
}
451452
}
452453

454+
private boolean checkMissingFilters(ReportNode subReportNode) {
455+
Map<UUID, String> filterNamesByUuid = new LinkedHashMap<>();
456+
generationDispatchInfos.getGeneratorsWithoutOutage().forEach(filterInfos -> filterNamesByUuid.put(filterInfos.getId(), filterInfos.getName()));
457+
generationDispatchInfos.getGeneratorsWithFixedSupply().forEach(filterInfos -> filterNamesByUuid.put(filterInfos.getId(), filterInfos.getName()));
458+
generationDispatchInfos.getGeneratorsFrequencyReserve().forEach(frequencyReserveInfos ->
459+
frequencyReserveInfos.getGeneratorsFilters().forEach(filterInfos -> filterNamesByUuid.put(filterInfos.getId(), filterInfos.getName()))
460+
);
461+
if (!filterNamesByUuid.isEmpty()) {
462+
List<AbstractFilter> filters = filterService.getFilters(new ArrayList<>(filterNamesByUuid.keySet()));
463+
Set<UUID> validFilters = filters.stream().map(AbstractFilter::getId).collect(Collectors.toSet());
464+
List<UUID> missingFilters = filterNamesByUuid.keySet().stream().filter(filterId -> !validFilters.contains(filterId)).toList();
465+
if (!missingFilters.isEmpty()) {
466+
report(subReportNode, "network.modification.missingFiltersInGenerationDispatch",
467+
Map.of("nb", missingFilters.size(), IS_PLURAL, missingFilters.size() > 1 ? "s" : ""),
468+
TypedValue.ERROR_SEVERITY);
469+
}
470+
return !missingFilters.isEmpty();
471+
} else {
472+
return false;
473+
}
474+
}
475+
453476
@Override
454477
public void apply(Network network, ReportNode subReportNode) {
478+
// check existence of all filters
479+
boolean missingFilters = checkMissingFilters(subReportNode);
480+
if (missingFilters) {
481+
return;
482+
}
483+
455484
Collection<Component> synchronousComponents = network.getBusView().getBusStream()
456485
.filter(Bus::isInMainConnectedComponent)
457486
.map(Bus::getSynchronousComponent)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,4 @@ network.modification.lcc.shuntCompensator.disconnected = Equipment with id=${id}
341341
network.modification.operationalLimitsGroup.creation = Creation of ${operationalLimitsGroupName}
342342
network.modification.operationalLimitsGroupPropertyValueNotFoundError = Cannot modify equipment ${id} : missing limit set applicable on side ${side} with property named ${propertyName} and with value ${propertyValue} : equipment ignored
343343
network.modification.operationalLimitsGroupPropertyValueMultipleError = Cannot modify equipment ${id} : multiple limit sets applicable on side ${side} with property named ${propertyName} and with value ${propertyValue} : equipment ignored
344+
network.modification.missingFiltersInGenerationDispatch = The modification points to at least ${nb} filter${isPlural} that does not exist anymore

src/test/java/org/gridsuite/modification/modifications/GenerationDispatchTest.java

Lines changed: 99 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
import com.powsybl.commons.report.ReportNode;
1010
import com.powsybl.iidm.network.IdentifiableType;
1111
import com.powsybl.iidm.network.Network;
12+
import org.gridsuite.filter.AbstractFilter;
1213
import org.gridsuite.filter.identifierlistfilter.FilterEquipments;
1314
import org.gridsuite.filter.identifierlistfilter.IdentifiableAttributes;
15+
import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter;
16+
import org.gridsuite.filter.utils.EquipmentType;
1417
import org.gridsuite.modification.IFilterService;
1518
import org.gridsuite.modification.NetworkModificationException;
1619
import org.gridsuite.modification.dto.*;
@@ -90,6 +93,15 @@ private void assertLogReportsForDefaultNetwork(double batteryBalanceOnSc2, Repor
9093
assertLogMessageWithoutRank("Sum of generator active power setpoints in SOUTH region: " + totalAmount + " MW (NUCLEAR: 0.0 MW, THERMAL: 0.0 MW, HYDRO: " + totalAmount + " MW, WIND AND SOLAR: 0.0 MW, OTHER: 0.0 MW).", "network.modification.SumGeneratorActivePower", report);
9194
}
9295

96+
@Override
97+
@Test
98+
public void testApply() throws Exception {
99+
GenerationDispatch modif = (GenerationDispatch) buildModification().toModification();
100+
modif.initApplicationContext(filterService, null);
101+
modif.apply(getNetwork());
102+
assertAfterNetworkModificationApplication();
103+
}
104+
93105
@Test
94106
void testGenerationDispatch() throws Exception {
95107
GenerationDispatchInfos modification = buildModification();
@@ -101,8 +113,9 @@ void testGenerationDispatch() throws Exception {
101113
.withAllResourceBundlesFromClasspath()
102114
.withMessageTemplate("test")
103115
.build());
104-
105-
modification.toModification().apply(getNetwork(), report);
116+
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
117+
modif.initApplicationContext(filterService, null);
118+
modif.apply(getNetwork(), report);
106119
assertNetworkAfterCreationWithStandardLossCoefficient();
107120

108121
assertLogReportsForDefaultNetwork(0., report);
@@ -123,7 +136,9 @@ void testGenerationDispatchWithBattery() throws Exception {
123136
ReportNode report = modification.createSubReportNode(ReportNode.newRootReportNode()
124137
.withAllResourceBundlesFromClasspath()
125138
.withMessageTemplate("test").build());
126-
modification.toModification().apply(getNetwork(), report);
139+
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
140+
modif.initApplicationContext(filterService, null);
141+
modif.apply(getNetwork(), report);
127142
assertLogReportsForDefaultNetwork(batteryTotalTargetP, report);
128143
}
129144

@@ -144,7 +159,9 @@ void testGenerationDispatchWithBatteryConnection() throws Exception {
144159
ReportNode report = modification.createSubReportNode(ReportNode.newRootReportNode()
145160
.withAllResourceBundlesFromClasspath()
146161
.withMessageTemplate("test").build());
147-
modification.toModification().apply(getNetwork(), report);
162+
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
163+
modif.initApplicationContext(filterService, null);
164+
modif.apply(getNetwork(), report);
148165
assertLogReportsForDefaultNetwork(batteryTotalTargetP, report);
149166
}
150167

@@ -157,7 +174,9 @@ void testGenerationDispatchWithMultipleEnergySource() throws Exception {
157174
ReportNode report = modification.createSubReportNode(ReportNode.newRootReportNode()
158175
.withAllResourceBundlesFromClasspath()
159176
.withMessageTemplate("test").build());
160-
modification.toModification().apply(getNetwork(), report);
177+
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
178+
modif.initApplicationContext(filterService, null);
179+
modif.apply(getNetwork(), report);
161180

162181
assertLogMessageWithoutRank("The total demand is : 768.0 MW", "network.modification.TotalDemand", report);
163182
assertLogMessageWithoutRank("The total amount of fixed supply is : 0.0 MW", "network.modification.TotalAmountFixedSupply", report);
@@ -179,7 +198,9 @@ void testGenerationDispatchWithHigherLossCoefficient() throws Exception {
179198
ReportNode report = modification.createSubReportNode(ReportNode.newRootReportNode()
180199
.withAllResourceBundlesFromClasspath()
181200
.withMessageTemplate("test").build());
182-
modification.toModification().apply(getNetwork(), report);
201+
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
202+
modif.initApplicationContext(filterService, null);
203+
modif.apply(getNetwork(), report);
183204

184205
assertEquals(100., getNetwork().getGenerator(GH1_ID).getTargetP(), 0.001);
185206
assertEquals(70., getNetwork().getGenerator(GH2_ID).getTargetP(), 0.001);
@@ -220,7 +241,9 @@ void testGenerationDispatchWithInternalHvdc() throws Exception {
220241
ReportNode report = modification.createSubReportNode(ReportNode.newRootReportNode()
221242
.withAllResourceBundlesFromClasspath()
222243
.withMessageTemplate("test").build());
223-
modification.toModification().apply(getNetwork(), report);
244+
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
245+
modif.initApplicationContext(filterService, null);
246+
modif.apply(getNetwork(), report);
224247

225248
assertEquals(100., getNetwork().getGenerator(GH1_ID).getTargetP(), 0.001);
226249
assertEquals(70., getNetwork().getGenerator(GH2_ID).getTargetP(), 0.001);
@@ -256,11 +279,18 @@ void testGenerationDispatchWithMaxPReduction() throws Exception {
256279
// network with 2 synchronous components, 2 hvdc lines between them, forcedOutageRate and plannedOutageRate defined for the generators
257280
setNetwork(Network.read("testGenerationDispatchReduceMaxP.xiidm", getClass().getResourceAsStream("/testGenerationDispatchReduceMaxP.xiidm")));
258281

259-
List<FilterEquipments> filters = List.of(new FilterEquipments(FILTER_ID_1, List.of(getIdentifiableAttributes(GTH2_ID), getIdentifiableAttributes(GROUP1_ID)), List.of()),
282+
List<FilterEquipments> filterEquipments = List.of(new FilterEquipments(FILTER_ID_1, List.of(getIdentifiableAttributes(GTH2_ID), getIdentifiableAttributes(GROUP1_ID)), List.of()),
260283
new FilterEquipments(FILTER_ID_2, List.of(getIdentifiableAttributes(ABC_ID), getIdentifiableAttributes(GH3_ID)), List.of()),
261284
new FilterEquipments(FILTER_ID_3, List.of(), List.of(GEN1_NOT_FOUND_ID, GEN2_NOT_FOUND_ID)));
262285

263-
when(filterService.exportFilters(List.of(FILTER_ID_1, FILTER_ID_2, FILTER_ID_3), getNetwork())).thenReturn(filters.stream());
286+
when(filterService.exportFilters(List.of(FILTER_ID_1, FILTER_ID_2, FILTER_ID_3), getNetwork())).thenReturn(filterEquipments.stream());
287+
288+
List<AbstractFilter> filters = List.of(
289+
new IdentifierListFilter(FILTER_ID_1, new Date(), EquipmentType.GENERATOR, List.of()),
290+
new IdentifierListFilter(FILTER_ID_2, new Date(), EquipmentType.GENERATOR, List.of()),
291+
new IdentifierListFilter(FILTER_ID_3, new Date(), EquipmentType.GENERATOR, List.of()));
292+
when(filterService.getFilters(List.of(FILTER_ID_1, FILTER_ID_2, FILTER_ID_3))).thenReturn(filters);
293+
264294
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
265295
modif.initApplicationContext(filterService, null);
266296
ReportNode report = modification.createSubReportNode(ReportNode.newRootReportNode()
@@ -323,6 +353,13 @@ void testGenerationDispatchGeneratorsWithFixedSupply() throws Exception {
323353
new FilterEquipments(FILTER_ID_4, List.of(getIdentifiableAttributes(TEST1_ID), getIdentifiableAttributes(GROUP2_ID)), List.of()));
324354
when(filterService.exportFilters(List.of(FILTER_ID_1, FILTER_ID_4), getNetwork())).thenReturn(filtersForFixedSupply.stream());
325355

356+
List<AbstractFilter> filters = List.of(
357+
new IdentifierListFilter(FILTER_ID_1, new Date(), EquipmentType.GENERATOR, List.of()),
358+
new IdentifierListFilter(FILTER_ID_2, new Date(), EquipmentType.GENERATOR, List.of()),
359+
new IdentifierListFilter(FILTER_ID_3, new Date(), EquipmentType.GENERATOR, List.of()),
360+
new IdentifierListFilter(FILTER_ID_4, new Date(), EquipmentType.GENERATOR, List.of()));
361+
when(filterService.getFilters(List.of(FILTER_ID_1, FILTER_ID_2, FILTER_ID_3, FILTER_ID_4))).thenReturn(filters);
362+
326363
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
327364
modif.initApplicationContext(filterService, null);
328365
ReportNode report = modification.createSubReportNode(ReportNode.newRootReportNode()
@@ -413,6 +450,15 @@ void testGenerationDispatchWithFrequencyReserve() throws Exception {
413450
when(filterService.exportFilters(List.of(FILTER_ID_4, FILTER_ID_5), getNetwork())).thenReturn(filtersForFrequencyReserve.stream());
414451
when(filterService.exportFilters(List.of(FILTER_ID_6), getNetwork())).thenReturn(getGeneratorsFrequencyReserveFilter6().stream());
415452

453+
List<AbstractFilter> filters = List.of(
454+
new IdentifierListFilter(FILTER_ID_1, new Date(), EquipmentType.GENERATOR, List.of()),
455+
new IdentifierListFilter(FILTER_ID_2, new Date(), EquipmentType.GENERATOR, List.of()),
456+
new IdentifierListFilter(FILTER_ID_3, new Date(), EquipmentType.GENERATOR, List.of()),
457+
new IdentifierListFilter(FILTER_ID_4, new Date(), EquipmentType.GENERATOR, List.of()),
458+
new IdentifierListFilter(FILTER_ID_5, new Date(), EquipmentType.GENERATOR, List.of()),
459+
new IdentifierListFilter(FILTER_ID_6, new Date(), EquipmentType.GENERATOR, List.of()));
460+
when(filterService.getFilters(List.of(FILTER_ID_1, FILTER_ID_2, FILTER_ID_3, FILTER_ID_4, FILTER_ID_5, FILTER_ID_6))).thenReturn(filters);
461+
416462
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
417463
modif.initApplicationContext(filterService, null);
418464
ReportNode report = modification.createSubReportNode(ReportNode.newRootReportNode()
@@ -463,8 +509,9 @@ void testGenerationDispatchWithSubstationsHierarchy() throws Exception {
463509

464510
// network
465511
setNetwork(Network.read("ieee118cdf_testDemGroupe.xiidm", getClass().getResourceAsStream("/ieee118cdf_testDemGroupe.xiidm")));
466-
467-
modification.toModification().apply(getNetwork());
512+
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
513+
modif.initApplicationContext(filterService, null);
514+
modif.apply(getNetwork());
468515

469516
// generators modified
470517
assertEquals(264, getNetwork().getGenerator("B4-G").getTargetP(), 0.001);
@@ -557,9 +604,11 @@ void testGenerationDispatchWithSubstationsHierarchyAndFixedSupply() {
557604
);
558605
when(filterService.exportFilters(List.of(FILTER_ID_1), getNetwork())).thenReturn(filtersForFixedSupply.stream());
559606

607+
List<AbstractFilter> filters = List.of(new IdentifierListFilter(FILTER_ID_1, new Date(), EquipmentType.GENERATOR, List.of()));
608+
when(filterService.getFilters(List.of(FILTER_ID_1))).thenReturn(filters);
609+
560610
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
561611
modif.initApplicationContext(filterService, null);
562-
563612
modif.apply(getNetwork());
564613

565614
// Check expected target active power values
@@ -628,6 +677,15 @@ void testGenerationDispatchWithMaxValueLessThanMinP() throws Exception {
628677
when(filterService.exportFilters(List.of(FILTER_ID_4, FILTER_ID_5), getNetwork())).thenReturn(getGeneratorsFrequencyReserveFilters45().stream());
629678
when(filterService.exportFilters(List.of(FILTER_ID_6), getNetwork())).thenReturn(getGeneratorsFrequencyReserveFilter6().stream());
630679

680+
List<AbstractFilter> filters = List.of(
681+
new IdentifierListFilter(FILTER_ID_1, new Date(), EquipmentType.GENERATOR, List.of()),
682+
new IdentifierListFilter(FILTER_ID_2, new Date(), EquipmentType.GENERATOR, List.of()),
683+
new IdentifierListFilter(FILTER_ID_3, new Date(), EquipmentType.GENERATOR, List.of()),
684+
new IdentifierListFilter(FILTER_ID_4, new Date(), EquipmentType.GENERATOR, List.of()),
685+
new IdentifierListFilter(FILTER_ID_5, new Date(), EquipmentType.GENERATOR, List.of()),
686+
new IdentifierListFilter(FILTER_ID_6, new Date(), EquipmentType.GENERATOR, List.of()));
687+
when(filterService.getFilters(List.of(FILTER_ID_1, FILTER_ID_2, FILTER_ID_3, FILTER_ID_4, FILTER_ID_5, FILTER_ID_6))).thenReturn(filters);
688+
631689
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
632690
modif.initApplicationContext(filterService, null);
633691
ReportNode report = modification.createSubReportNode(ReportNode.newRootReportNode()
@@ -708,6 +766,35 @@ protected void checkModification() {
708766
modification.setDefaultOutageRate(140.);
709767
e = assertThrows(NetworkModificationException.class, () -> modification.toModification().check(getNetwork()));
710768
assertEquals("GENERATION_DISPATCH_ERROR : The default outage rate must be between 0 and 100", e.getMessage());
769+
}
770+
771+
@Test
772+
void testGenerationDispatchWithMissingFilters() {
773+
GenerationDispatchInfos modification = buildModification();
774+
modification.setDefaultOutageRate(15.);
775+
modification.setGeneratorsWithoutOutage(
776+
List.of(GeneratorsFilterInfos.builder().id(FILTER_ID_1).name("filter1").build(),
777+
GeneratorsFilterInfos.builder().id(FILTER_ID_2).name("filter2").build(),
778+
GeneratorsFilterInfos.builder().id(FILTER_ID_3).name("filter3").build()));
779+
modification.setGeneratorsWithFixedSupply(
780+
List.of(GeneratorsFilterInfos.builder().id(FILTER_ID_1).name("filter1").build(),
781+
GeneratorsFilterInfos.builder().id(FILTER_ID_2).name("filter2").build(),
782+
GeneratorsFilterInfos.builder().id(FILTER_ID_3).name("filter3").build()));
783+
modification.setGeneratorsFrequencyReserve(List.of(GeneratorsFrequencyReserveInfos.builder().frequencyReserve(3.)
784+
.generatorsFilters(List.of(GeneratorsFilterInfos.builder().id(FILTER_ID_4).name("filter4").build(),
785+
GeneratorsFilterInfos.builder().id(FILTER_ID_5).name("filter5").build())).build(),
786+
GeneratorsFrequencyReserveInfos.builder().frequencyReserve(5.)
787+
.generatorsFilters(List.of(GeneratorsFilterInfos.builder().id(FILTER_ID_6).name("filter6").build())).build()));
711788

789+
// network with 2 synchronous components, 2 hvdc lines between them, forcedOutageRate and plannedOutageRate defined for the generators
790+
setNetwork(Network.read("testGenerationDispatchReduceMaxP.xiidm", getClass().getResourceAsStream("/testGenerationDispatchReduceMaxP.xiidm")));
791+
792+
GenerationDispatch modif = (GenerationDispatch) modification.toModification();
793+
modif.initApplicationContext(filterService, null);
794+
ReportNode report = modification.createSubReportNode(ReportNode.newRootReportNode()
795+
.withAllResourceBundlesFromClasspath()
796+
.withMessageTemplate("test").build());
797+
modif.apply(getNetwork(), report);
798+
assertLogMessage("The modification points to at least 6 filters that does not exist anymore", "network.modification.missingFiltersInGenerationDispatch", report);
712799
}
713800
}

0 commit comments

Comments
 (0)