11
11
import com .powsybl .commons .report .TypedValue ;
12
12
import com .powsybl .iidm .network .*;
13
13
import com .powsybl .iidm .network .extensions .*;
14
+ import jakarta .validation .constraints .NotNull ;
14
15
import org .gridsuite .modification .NetworkModificationException ;
15
16
import org .gridsuite .modification .dto .*;
16
17
import org .gridsuite .modification .utils .ModificationUtils ;
@@ -380,20 +381,24 @@ public boolean isThisLimitDeleted(List<CurrentTemporaryLimitModificationInfos> t
380
381
.anyMatch (temporaryLimit -> temporaryLimit .getAcceptableDuration () == acceptableDuration && temporaryLimit .getModificationType () == TemporaryLimitModificationType .DELETE );
381
382
}
382
383
383
- protected void modifyTemporaryLimits (OperationalLimitsGroupModificationInfos operationalLimitsGroupModificationInfos ,
384
+ /**
385
+ * This function removes all the temporary limits of the 'currentLimits' concerned and recreates them (except in case of deletion)
386
+ */
387
+ protected void modifyTemporaryLimits (@ NotNull OperationalLimitsGroupModificationInfos operationalLimitsGroupModificationInfos ,
384
388
CurrentLimitsAdder limitsAdder ,
385
389
CurrentLimits currentLimits ,
386
390
List <ReportNode > limitsReports ) {
387
391
CurrentLimitsModificationInfos currentLimitsInfos = operationalLimitsGroupModificationInfos .getCurrentLimits ();
388
392
389
- // we create a mutable list of temporary limits to be able to remove the limits that are modified in current modification
390
- List <LoadingLimits .TemporaryLimit > branchTemporaryLimits = new ArrayList <>();
391
- boolean areLimitsReplaced = operationalLimitsGroupModificationInfos != null && TemporaryLimitModificationType .REPLACE .equals (operationalLimitsGroupModificationInfos .getTemporaryLimitsModificationType ());
393
+ // we create a mutable list of temporary limits to be able to remove the limits that are modified in this current modification
394
+ // those left at the end of the network modification are those that have not been modified (or deleted)
395
+ List <LoadingLimits .TemporaryLimit > unmodifiedTemporaryLimits = new ArrayList <>();
396
+ boolean areLimitsReplaced = TemporaryLimitModificationType .REPLACE .equals (operationalLimitsGroupModificationInfos .getTemporaryLimitsModificationType ());
392
397
if (currentLimits != null && !areLimitsReplaced ) {
393
- branchTemporaryLimits .addAll (currentLimits .getTemporaryLimits ());
398
+ unmodifiedTemporaryLimits .addAll (currentLimits .getTemporaryLimits ());
394
399
}
395
400
List <ReportNode > temporaryLimitsReports = new ArrayList <>();
396
- if (operationalLimitsGroupModificationInfos != null && TemporaryLimitModificationType . REPLACE . equals ( operationalLimitsGroupModificationInfos . getTemporaryLimitsModificationType ()) ) {
401
+ if (areLimitsReplaced ) {
397
402
temporaryLimitsReports .add (ReportNode .newRootReportNode ()
398
403
.withAllResourceBundlesFromClasspath ()
399
404
.withMessageTemplate ("network.modification.temporaryLimitsReplaced" )
@@ -403,98 +408,24 @@ protected void modifyTemporaryLimits(OperationalLimitsGroupModificationInfos ope
403
408
404
409
if (currentLimitsInfos != null && currentLimitsInfos .getTemporaryLimits () != null ) {
405
410
for (CurrentTemporaryLimitModificationInfos limit : currentLimitsInfos .getTemporaryLimits ()) {
406
- int limitAcceptableDuration = limit .getAcceptableDuration () == null ? Integer .MAX_VALUE : limit .getAcceptableDuration ();
407
- double limitValue = limit .getValue () == null ? Double .MAX_VALUE : limit .getValue ();
408
- String limitDurationToReport = limitAcceptableDuration == Integer .MAX_VALUE ? " " : String .valueOf (limitAcceptableDuration );
409
- String limitValueToReport = limitValue == Double .MAX_VALUE ? "no value" : String .valueOf (limitValue );
410
- LoadingLimits .TemporaryLimit limitToModify = null ;
411
- if (currentLimits != null ) {
412
- limitToModify = currentLimits .getTemporaryLimit (limitAcceptableDuration );
413
- if (limitToModify != null && !limitToModify .getName ().equals (limit .getName ())) {
414
- boolean isThisLimitDeleted = isThisLimitDeleted (currentLimitsInfos .getTemporaryLimits (), limitAcceptableDuration );
415
- if (isThisLimitDeleted ) {
416
- limitToModify = null ;
417
- } else if (TemporaryLimitModificationType .ADD .equals (limit .getModificationType ())) {
418
- throw new PowsyblException ("2 temporary limits have the same duration " + limitAcceptableDuration );
419
- }
420
- }
421
-
422
- //Additional check for limit sets tabular modifications
423
- if (operationalLimitsGroupModificationInfos != null && TemporaryLimitModificationType .ADD .equals (operationalLimitsGroupModificationInfos .getTemporaryLimitsModificationType ())) {
424
- currentLimits .getTemporaryLimits ().stream ().filter (temporaryLimit -> temporaryLimit .getName ().equals (limit .getName ())).findFirst ().ifPresent (temporaryLimit -> {
425
- throw new PowsyblException ("2 temporary limits have the same name " + limit .getName ());
426
- });
427
- }
428
- // we remove the limit to modify from the list of temporary limits so we can get the list of temporary limits coming from previous modifications
429
- branchTemporaryLimits .removeIf (temporaryLimit -> temporaryLimit .getAcceptableDuration () == limitAcceptableDuration );
430
- }
431
- if (limitToModify == null && limit .getModificationType () == TemporaryLimitModificationType .ADD || limit .getModificationType () == TemporaryLimitModificationType .REPLACE ) {
432
- temporaryLimitsReports .add (ReportNode .newRootReportNode ()
433
- .withAllResourceBundlesFromClasspath ()
434
- .withMessageTemplate ("network.modification.temporaryLimitAdded.name" )
435
- .withUntypedValue (NAME , limit .getName ())
436
- .withUntypedValue (DURATION , limitDurationToReport )
437
- .withUntypedValue (VALUE , limitValueToReport )
438
- .withSeverity (TypedValue .INFO_SEVERITY )
439
- .build ());
440
-
441
- } else if (limitToModify != null ) {
442
- if (limit .getModificationType () == TemporaryLimitModificationType .DELETE ) {
443
- temporaryLimitsReports .add (ReportNode .newRootReportNode ()
444
- .withAllResourceBundlesFromClasspath ()
445
- .withMessageTemplate ("network.modification.temporaryLimitDeleted.name" )
446
- .withUntypedValue (NAME , limit .getName ())
447
- .withUntypedValue (DURATION , limitDurationToReport )
448
- .withSeverity (TypedValue .INFO_SEVERITY )
449
- .build ());
450
- continue ;
451
- } else if (Double .compare (limitToModify .getValue (), limitValue ) != 0 && limit .getModificationType () != null ) {
452
- temporaryLimitsReports .add (ReportNode .newRootReportNode ()
453
- .withAllResourceBundlesFromClasspath ()
454
- .withMessageTemplate ("network.modification.temporaryLimitModified.name" )
455
- .withUntypedValue (NAME , limit .getName ())
456
- .withUntypedValue (DURATION , limitDurationToReport )
457
- .withUntypedValue (VALUE , limitValueToReport )
458
- .withUntypedValue ("oldValue" ,
459
- limitToModify .getValue () == Double .MAX_VALUE ? "no value"
460
- : String .valueOf (limitToModify .getValue ()))
461
- .withSeverity (TypedValue .INFO_SEVERITY )
462
- .build ());
463
- } else {
464
- limitValue = limitToModify .getValue ();
465
- }
466
- } else if (limit .getModificationType () == TemporaryLimitModificationType .MODIFY ) {
467
- temporaryLimitsReports .add (ReportNode .newRootReportNode ()
468
- .withAllResourceBundlesFromClasspath ()
469
- .withMessageTemplate ("network.modification.temporaryLimitsNoMatch" )
470
- .withUntypedValue (LIMIT_ACCEPTABLE_DURATION , limitAcceptableDuration )
471
- .withSeverity (TypedValue .WARN_SEVERITY )
472
- .build ());
473
- continue ;
474
- } else {
475
- continue ;
476
- }
477
- limitsAdder
478
- .beginTemporaryLimit ()
479
- .setName (limit .getName ())
480
- .setValue (limitValue )
481
- .setAcceptableDuration (limitAcceptableDuration )
482
- .endTemporaryLimit ();
411
+ applyTemporaryLimitModification (
412
+ operationalLimitsGroupModificationInfos ,
413
+ limitsAdder ,
414
+ currentLimits ,
415
+ limit ,
416
+ unmodifiedTemporaryLimits ,
417
+ temporaryLimitsReports
418
+ );
483
419
}
484
420
}
485
- // we add the temporary limits comming from previous modifications
486
- if (!branchTemporaryLimits .isEmpty ()) {
487
- for (LoadingLimits .TemporaryLimit limit : branchTemporaryLimits ) {
488
- limitsAdder
489
- .beginTemporaryLimit ()
490
- .setName (limit .getName ())
491
- .setValue (limit .getValue ())
492
- .setAcceptableDuration (limit .getAcceptableDuration ())
493
- .endTemporaryLimit ();
421
+ // we add (back) the temporary limits that have not been modified
422
+ if (!unmodifiedTemporaryLimits .isEmpty ()) {
423
+ for (LoadingLimits .TemporaryLimit limit : unmodifiedTemporaryLimits ) {
424
+ addTemporaryLimit (limitsAdder , limit .getName (), limit .getValue (), limit .getAcceptableDuration ());
494
425
}
495
426
}
496
427
if (!temporaryLimitsReports .isEmpty ()) {
497
- temporaryLimitsReports .add ( 0 , ReportNode .newRootReportNode ()
428
+ temporaryLimitsReports .addFirst ( ReportNode .newRootReportNode ()
498
429
.withAllResourceBundlesFromClasspath ()
499
430
.withMessageTemplate ("network.modification.temporaryLimitsModification" )
500
431
.withSeverity (TypedValue .INFO_SEVERITY )
@@ -503,6 +434,148 @@ protected void modifyTemporaryLimits(OperationalLimitsGroupModificationInfos ope
503
434
}
504
435
}
505
436
437
+ private static boolean mayCreateALimit (TemporaryLimitModificationType modificationType ) {
438
+ return modificationType == TemporaryLimitModificationType .ADD
439
+ || modificationType == TemporaryLimitModificationType .REPLACE
440
+ || modificationType == TemporaryLimitModificationType .MODIFY_OR_ADD ;
441
+ }
442
+
443
+ /**
444
+ * modify a specific limit
445
+ * @param operationalLimitsGroupModificationInfos part of the network modification containing the operational limits groups data
446
+ * @param limitsAdder adder which receives all the "validated" limits to be added at the end
447
+ * @param networkCurrentLimits limits of the branch which is currently modified by the network modification
448
+ * @param limit modification to be applied to the limit
449
+ * @param unmodifiedTemporaryLimits list of all the unmodified limits that will be added at the end of the network modification
450
+ * @param temporaryLimitsReports log report
451
+ */
452
+ private void applyTemporaryLimitModification (
453
+ OperationalLimitsGroupModificationInfos operationalLimitsGroupModificationInfos ,
454
+ CurrentLimitsAdder limitsAdder ,
455
+ CurrentLimits networkCurrentLimits ,
456
+ CurrentTemporaryLimitModificationInfos limit ,
457
+ List <LoadingLimits .TemporaryLimit > unmodifiedTemporaryLimits ,
458
+ List <ReportNode > temporaryLimitsReports ) {
459
+ CurrentLimitsModificationInfos currentLimitsInfos = operationalLimitsGroupModificationInfos .getCurrentLimits ();
460
+ int limitAcceptableDuration = limit .getAcceptableDuration () == null ? Integer .MAX_VALUE : limit .getAcceptableDuration ();
461
+ double limitValue = limit .getValue () == null ? Double .MAX_VALUE : limit .getValue ();
462
+ String limitDurationToReport = limitAcceptableDuration == Integer .MAX_VALUE ? " " : String .valueOf (limitAcceptableDuration );
463
+ String limitValueToReport = limitValue == Double .MAX_VALUE ? "no value" : String .valueOf (limitValue );
464
+ LoadingLimits .TemporaryLimit limitToModify = null ;
465
+ if (networkCurrentLimits != null ) {
466
+ limitToModify = getTemporaryLimitToModify (networkCurrentLimits , limit , currentLimitsInfos , operationalLimitsGroupModificationInfos .getTemporaryLimitsModificationType ());
467
+ // this limit is modified by the network modification so we remove it from the list of unmodified temporary limits
468
+ unmodifiedTemporaryLimits .removeIf (temporaryLimit -> temporaryLimit .getAcceptableDuration () == limitAcceptableDuration );
469
+ }
470
+ if (limitToModify == null && mayCreateALimit (limit .getModificationType ())) {
471
+ createTemporaryLimit (limitsAdder , limit , temporaryLimitsReports , limitDurationToReport , limitValueToReport , limitValue , limitAcceptableDuration );
472
+ } else if (limitToModify != null ) {
473
+ // the limit already exists
474
+ if (limit .getModificationType () == TemporaryLimitModificationType .DELETE ) {
475
+ // the limit has been removed previously
476
+ temporaryLimitsReports .add (ReportNode .newRootReportNode ()
477
+ .withAllResourceBundlesFromClasspath ()
478
+ .withMessageTemplate ("network.modification.temporaryLimitDeleted.name" )
479
+ .withUntypedValue (NAME , limit .getName ())
480
+ .withUntypedValue (DURATION , limitDurationToReport )
481
+ .withSeverity (TypedValue .INFO_SEVERITY )
482
+ .build ());
483
+ } else {
484
+ modifyTemporaryLimit (limitsAdder , limit , temporaryLimitsReports , limitToModify , limitValue , limitDurationToReport , limitValueToReport , limitAcceptableDuration );
485
+ }
486
+ } else if (limit .getModificationType () == TemporaryLimitModificationType .MODIFY || limit .getModificationType () == TemporaryLimitModificationType .MODIFY_OR_ADD ) {
487
+ // invalid modification
488
+ temporaryLimitsReports .add (ReportNode .newRootReportNode ()
489
+ .withAllResourceBundlesFromClasspath ()
490
+ .withMessageTemplate ("network.modification.temporaryLimitsNoMatch" )
491
+ .withUntypedValue (LIMIT_ACCEPTABLE_DURATION , limitAcceptableDuration )
492
+ .withSeverity (TypedValue .WARN_SEVERITY )
493
+ .build ());
494
+ }
495
+ }
496
+
497
+ private static void modifyTemporaryLimit (
498
+ CurrentLimitsAdder limitsAdder ,
499
+ CurrentTemporaryLimitModificationInfos limitModificationInfos ,
500
+ List <ReportNode > temporaryLimitsReports ,
501
+ LoadingLimits .TemporaryLimit limitToModify ,
502
+ double limitValue ,
503
+ String limitDurationToReport ,
504
+ String limitValueToReport ,
505
+ int limitAcceptableDuration ) {
506
+ if (Double .compare (limitToModify .getValue (), limitValue ) != 0 && limitModificationInfos .getModificationType () != null ) {
507
+ temporaryLimitsReports .add (ReportNode .newRootReportNode ()
508
+ .withAllResourceBundlesFromClasspath ()
509
+ .withMessageTemplate ("network.modification.temporaryLimitModified.name" )
510
+ .withUntypedValue (NAME , limitModificationInfos .getName ())
511
+ .withUntypedValue (DURATION , limitDurationToReport )
512
+ .withUntypedValue (VALUE , limitValueToReport )
513
+ .withUntypedValue ("oldValue" ,
514
+ limitToModify .getValue () == Double .MAX_VALUE ? "no value"
515
+ : String .valueOf (limitToModify .getValue ()))
516
+ .withSeverity (TypedValue .INFO_SEVERITY )
517
+ .build ());
518
+ addTemporaryLimit (limitsAdder , limitModificationInfos .getName (), limitValue , limitAcceptableDuration );
519
+ } else {
520
+ // no real modification
521
+ addTemporaryLimit (limitsAdder , limitModificationInfos .getName (), limitToModify .getValue (), limitAcceptableDuration );
522
+ }
523
+ }
524
+
525
+ private static void createTemporaryLimit (
526
+ CurrentLimitsAdder limitsAdder ,
527
+ CurrentTemporaryLimitModificationInfos limit ,
528
+ List <ReportNode > temporaryLimitsReports ,
529
+ String limitDurationToReport ,
530
+ String limitValueToReport ,
531
+ double limitValue ,
532
+ int limitAcceptableDuration ) {
533
+ temporaryLimitsReports .add (ReportNode .newRootReportNode ()
534
+ .withAllResourceBundlesFromClasspath ()
535
+ .withMessageTemplate ("network.modification.temporaryLimitAdded.name" )
536
+ .withUntypedValue (NAME , limit .getName ())
537
+ .withUntypedValue (DURATION , limitDurationToReport )
538
+ .withUntypedValue (VALUE , limitValueToReport )
539
+ .withSeverity (TypedValue .INFO_SEVERITY )
540
+ .build ());
541
+ addTemporaryLimit (limitsAdder , limit .getName (), limitValue , limitAcceptableDuration );
542
+ }
543
+
544
+ private static void addTemporaryLimit (CurrentLimitsAdder limitsAdder , String limit , double limitValue , int limitAcceptableDuration ) {
545
+ limitsAdder
546
+ .beginTemporaryLimit ()
547
+ .setName (limit )
548
+ .setValue (limitValue )
549
+ .setAcceptableDuration (limitAcceptableDuration )
550
+ .endTemporaryLimit ();
551
+ }
552
+
553
+ private LoadingLimits .TemporaryLimit getTemporaryLimitToModify (
554
+ CurrentLimits networkCurrentLimits ,
555
+ CurrentTemporaryLimitModificationInfos limit ,
556
+ CurrentLimitsModificationInfos currentLimitsInfos ,
557
+ TemporaryLimitModificationType temporaryLimitsModificationType ) {
558
+ int limitAcceptableDuration = limit .getAcceptableDuration () == null ? Integer .MAX_VALUE : limit .getAcceptableDuration ();
559
+ LoadingLimits .TemporaryLimit limitToModify ;
560
+ limitToModify = networkCurrentLimits .getTemporaryLimit (limitAcceptableDuration );
561
+ if (limitToModify != null && !limitToModify .getName ().equals (limit .getName ())) {
562
+ boolean isThisLimitDeleted = isThisLimitDeleted (currentLimitsInfos .getTemporaryLimits (), limitAcceptableDuration );
563
+ if (isThisLimitDeleted ) {
564
+ limitToModify = null ;
565
+ } else if (TemporaryLimitModificationType .ADD .equals (limit .getModificationType ())) {
566
+ throw new PowsyblException ("2 temporary limits have the same duration " + limitAcceptableDuration );
567
+ }
568
+ }
569
+
570
+ //Additional check for limit sets tabular modifications
571
+ if (TemporaryLimitModificationType .ADD .equals (temporaryLimitsModificationType )) {
572
+ networkCurrentLimits .getTemporaryLimits ().stream ().filter (temporaryLimit -> temporaryLimit .getName ().equals (limit .getName ())).findFirst ().ifPresent (temporaryLimit -> {
573
+ throw new PowsyblException ("2 temporary limits have the same name " + limit .getName ());
574
+ });
575
+ }
576
+ return limitToModify ;
577
+ }
578
+
506
579
protected boolean characteristicsModified (BranchModificationInfos branchModificationInfos ) {
507
580
return branchModificationInfos .getX () != null
508
581
&& branchModificationInfos .getX ().getValue () != null
0 commit comments