NcRemedialActionsCreator.java
/*
* Copyright (c) 2023, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.powsybl.openrao.data.crac.io.nc.craccreator.remedialaction;
import com.powsybl.openrao.data.crac.api.usagerule.OnConstraint;
import com.powsybl.openrao.data.crac.api.usagerule.OnContingencyState;
import com.powsybl.openrao.data.crac.api.usagerule.OnInstant;
import com.powsybl.openrao.data.crac.api.usagerule.UsageMethod;
import com.powsybl.openrao.data.crac.api.usagerule.UsageRule;
import com.powsybl.openrao.data.crac.io.nc.NcCrac;
import com.powsybl.openrao.data.crac.io.nc.craccreator.NcCracCreationContext;
import com.powsybl.openrao.data.crac.io.nc.craccreator.NcCracUtils;
import com.powsybl.openrao.data.crac.io.nc.craccreator.NcAggregator;
import com.powsybl.openrao.data.crac.io.nc.craccreator.constants.RemedialActionKind;
import com.powsybl.openrao.data.crac.io.nc.objects.AssessedElementWithRemedialAction;
import com.powsybl.openrao.data.crac.io.nc.objects.ContingencyWithRemedialAction;
import com.powsybl.openrao.data.crac.io.nc.objects.GridStateAlterationRemedialAction;
import com.powsybl.openrao.data.crac.io.nc.objects.RemedialActionDependency;
import com.powsybl.openrao.data.crac.io.nc.objects.TapChanger;
import com.powsybl.openrao.data.crac.io.nc.objects.TapPositionAction;
import com.powsybl.openrao.data.crac.api.cnec.Cnec;
import com.powsybl.action.*;
import com.powsybl.iidm.network.Network;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.api.Instant;
import com.powsybl.openrao.data.crac.api.InstantKind;
import com.powsybl.openrao.data.crac.api.RemedialActionAdder;
import com.powsybl.openrao.data.crac.api.networkaction.ActionType;
import com.powsybl.openrao.data.crac.api.networkaction.NetworkAction;
import com.powsybl.openrao.data.crac.api.networkaction.NetworkActionAdder;
import com.powsybl.openrao.data.crac.io.commons.api.ElementaryCreationContext;
import com.powsybl.openrao.data.crac.io.commons.api.ImportStatus;
import com.powsybl.openrao.data.crac.io.commons.api.StandardElementaryCreationContext;
import com.powsybl.openrao.data.crac.io.commons.OpenRaoImportException;
import com.powsybl.openrao.data.crac.io.nc.parameters.NcCracCreationParameters;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Mohamed Ben-rejeb {@literal <mohamed.ben-rejeb at rte-france.com>}
*/
public class NcRemedialActionsCreator {
private final Crac crac;
Map<String, ElementaryCreationContext> contextByRaId = new TreeMap<>();
private final ElementaryActionsHelper elementaryActionsHelper;
private final NetworkActionCreator networkActionCreator;
private final PstRangeActionCreator pstRangeActionCreator;
private final Set<GridStateAlterationRemedialAction> nativeRemedialActions;
private final NcCracCreationParameters ncCracCreationParameters;
public NcRemedialActionsCreator(Crac crac, Network network, NcCrac nativeCrac, NcCracCreationContext cracCreationContext, Set<ElementaryCreationContext> cnecCreationContexts, NcCracCreationParameters ncCracCreationParameters) {
this.crac = crac;
this.elementaryActionsHelper = new ElementaryActionsHelper(nativeCrac);
this.networkActionCreator = new NetworkActionCreator(this.crac, network);
this.ncCracCreationParameters = ncCracCreationParameters;
Map<String, String> pstPerTapChanger = new NcAggregator<>(TapChanger::powerTransformer).aggregate(nativeCrac.getTapChangers()).entrySet().stream().collect(Collectors.toMap(entry -> entry.getValue().iterator().next().mrid(), Map.Entry::getKey));
this.pstRangeActionCreator = new PstRangeActionCreator(this.crac, network, pstPerTapChanger);
Map<String, Set<AssessedElementWithRemedialAction>> linkedAeWithRa = new NcAggregator<>(AssessedElementWithRemedialAction::remedialAction).aggregate(nativeCrac.getAssessedElementWithRemedialActions());
Map<String, Set<ContingencyWithRemedialAction>> linkedCoWithRa = new NcAggregator<>(ContingencyWithRemedialAction::remedialAction).aggregate(nativeCrac.getContingencyWithRemedialActions());
this.nativeRemedialActions = new HashSet<>(nativeCrac.getGridStateAlterationRemedialActions());
createRemedialActions(linkedAeWithRa, linkedCoWithRa, cnecCreationContexts);
// standaloneRaIdsImplicatedIntoAGroup contain ids of Ra's depending on a group whether the group is imported or not
Set<String> standaloneRaIdsImplicatedIntoAGroup = createRemedialActionGroups();
standaloneRaIdsImplicatedIntoAGroup.forEach(crac::removeRemedialAction);
standaloneRaIdsImplicatedIntoAGroup.forEach(importedRaId -> contextByRaId.remove(importedRaId));
cracCreationContext.setRemedialActionCreationContexts(new HashSet<>(contextByRaId.values()));
}
private void createRemedialActions(Map<String, Set<AssessedElementWithRemedialAction>> linkedAeWithRa, Map<String, Set<ContingencyWithRemedialAction>> linkedCoWithRa, Set<ElementaryCreationContext> cnecCreationContexts) {
for (GridStateAlterationRemedialAction nativeRemedialAction : nativeRemedialActions) {
List<String> alterations = new ArrayList<>();
try {
checkKind(nativeRemedialAction);
if (!nativeRemedialAction.normalAvailable()) {
throw new OpenRaoImportException(ImportStatus.NOT_FOR_RAO, String.format("Remedial action %s will not be imported because it is set as unavailable", nativeRemedialAction.mrid()));
}
RemedialActionType remedialActionType = getRemedialActionType(nativeRemedialAction.mrid(), nativeRemedialAction.mrid());
RemedialActionAdder<?> remedialActionAdder;
if (remedialActionType.equals(RemedialActionType.NETWORK_ACTION)) {
remedialActionAdder = networkActionCreator.getNetworkActionAdder(elementaryActionsHelper.getTopologyActions(), elementaryActionsHelper.getRotatingMachineActions(), elementaryActionsHelper.getShuntCompensatorModifications(), elementaryActionsHelper.getNativeStaticPropertyRangesPerNativeGridStateAlteration(), nativeRemedialAction.mrid(), nativeRemedialAction.mrid(), alterations);
fillAndSaveRemedialActionAdderAndContext(linkedAeWithRa, linkedCoWithRa, cnecCreationContexts, nativeRemedialAction, alterations, remedialActionType, remedialActionAdder, nativeRemedialAction.getUniqueName());
} else {
if (elementaryActionsHelper.getTapPositionActions().get(nativeRemedialAction.mrid()).size() > 1) {
// group TapPositionAction's
for (TapPositionAction nativeTapPositionAction : elementaryActionsHelper.getTapPositionActions().get(nativeRemedialAction.mrid())) {
try {
remedialActionAdder = pstRangeActionCreator.getPstRangeActionAdder(true, nativeRemedialAction.mrid(), nativeTapPositionAction, elementaryActionsHelper.getNativeStaticPropertyRangesPerNativeGridStateAlteration(), nativeTapPositionAction.mrid());
fillAndSaveRemedialActionAdderAndContext(linkedAeWithRa, linkedCoWithRa, cnecCreationContexts, nativeRemedialAction, alterations, remedialActionType, remedialActionAdder, createNameFromTapPositionAction(nativeTapPositionAction.mrid(), nativeRemedialAction.operator()));
} catch (OpenRaoImportException e) {
if (e.getImportStatus().equals(ImportStatus.NOT_FOR_RAO)) {
contextByRaId.put(nativeTapPositionAction.mrid(), StandardElementaryCreationContext.notImported(nativeTapPositionAction.mrid(), null, e.getImportStatus(), e.getMessage()));
} else {
throw e;
}
}
}
} else {
remedialActionAdder = pstRangeActionCreator.getPstRangeActionAdder(false, nativeRemedialAction.mrid(), elementaryActionsHelper.getTapPositionActions().get(nativeRemedialAction.mrid()).iterator().next(), elementaryActionsHelper.getNativeStaticPropertyRangesPerNativeGridStateAlteration(), nativeRemedialAction.mrid());
fillAndSaveRemedialActionAdderAndContext(linkedAeWithRa, linkedCoWithRa, cnecCreationContexts, nativeRemedialAction, alterations, remedialActionType, remedialActionAdder, nativeRemedialAction.getUniqueName());
}
}
} catch (OpenRaoImportException e) {
contextByRaId.put(nativeRemedialAction.mrid(), StandardElementaryCreationContext.notImported(nativeRemedialAction.mrid(), null, e.getImportStatus(), e.getMessage()));
}
}
}
private String createNameFromTapPositionAction(String tapPositionId, String operator) {
if (operator != null) {
return NcCracUtils.getTsoNameFromUrl(operator) + "-" + tapPositionId;
} else {
return tapPositionId;
}
}
private void fillAndSaveRemedialActionAdderAndContext(Map<String, Set<AssessedElementWithRemedialAction>> linkedAeWithRa, Map<String, Set<ContingencyWithRemedialAction>> linkedCoWithRa,
Set<ElementaryCreationContext> cnecCreationContexts, GridStateAlterationRemedialAction nativeRemedialAction, List<String> alterations,
RemedialActionType remedialActionType, RemedialActionAdder<?> remedialActionAdder, String remedialActionName) {
remedialActionAdder.withName(remedialActionName);
if (nativeRemedialAction.operator() != null) {
remedialActionAdder.withOperator(NcCracUtils.getTsoNameFromUrl(nativeRemedialAction.operator()));
}
if (nativeRemedialAction.getTimeToImplementInSeconds() != null) {
remedialActionAdder.withSpeed(nativeRemedialAction.getTimeToImplementInSeconds());
} else if (!nativeRemedialAction.isManual() && remedialActionType == RemedialActionType.PST_RANGE_ACTION) {
throw new OpenRaoImportException(ImportStatus.INCONSISTENCY_IN_DATA, String.format("Remedial action %s will not be imported because an auto PST range action must have a speed defined", nativeRemedialAction.mrid()));
}
InstantKind instantKind = getInstantKind(nativeRemedialAction);
Set<Instant> instants = getInstants(instantKind, nativeRemedialAction.operator() == null ? null : NcCracUtils.getTsoNameFromUrl(nativeRemedialAction.operator()));
instants.forEach(instant -> addUsageRules(nativeRemedialAction.mrid(), linkedAeWithRa.getOrDefault(nativeRemedialAction.mrid(), Set.of()), linkedCoWithRa.getOrDefault(nativeRemedialAction.mrid(), Set.of()), cnecCreationContexts, remedialActionAdder, alterations, instant));
remedialActionAdder.add();
if (alterations.isEmpty()) {
contextByRaId.put(nativeRemedialAction.mrid(), StandardElementaryCreationContext.imported(nativeRemedialAction.mrid(), null, nativeRemedialAction.mrid(), false, ""));
} else {
contextByRaId.put(nativeRemedialAction.mrid(), StandardElementaryCreationContext.imported(nativeRemedialAction.mrid(), null, nativeRemedialAction.mrid(), true, String.join(". ", alterations)));
}
}
private Set<Instant> getInstants(InstantKind instantKind, String operator) {
Set<Instant> instants = crac.getInstants(instantKind);
if (instantKind == InstantKind.CURATIVE && operator != null && ncCracCreationParameters.getRestrictedCurativeBatchesPerTso().containsKey(operator)) {
return instants.stream().filter(instant -> ncCracCreationParameters.getRestrictedCurativeBatchesPerTso().get(operator).contains(instant.getId())).collect(Collectors.toSet());
}
return instants;
}
private void addUsageRules(String remedialActionId, Set<AssessedElementWithRemedialAction> linkedAssessedElementWithRemedialActions, Set<ContingencyWithRemedialAction> linkedContingencyWithRemedialActions, Set<ElementaryCreationContext> cnecCreationContexts, RemedialActionAdder<?>
remedialActionAdder, List<String> alterations, Instant instant) {
if (addOnConstraintUsageRules(remedialActionId, linkedAssessedElementWithRemedialActions, linkedContingencyWithRemedialActions, cnecCreationContexts, remedialActionAdder, alterations, instant)) {
return;
}
if (addOnContingencyStateUsageRules(remedialActionId, linkedContingencyWithRemedialActions, remedialActionAdder, alterations, instant)) {
return;
}
addOnInstantUsageRules(remedialActionId, remedialActionAdder, instant);
}
private boolean addOnConstraintUsageRules(String
remedialActionId, Set<AssessedElementWithRemedialAction> linkedAssessedElementWithRemedialActions, Set<ContingencyWithRemedialAction> linkedContingencyWithRemedialActions, Set<ElementaryCreationContext> cnecCreationContexts, RemedialActionAdder<?>
remedialActionAdder, List<String> alterations, Instant instant) {
Map<String, AssociationStatus> cnecStatusMap = OnConstraintUsageRuleHelper.processCnecsLinkedToRemedialAction(crac, remedialActionId, linkedAssessedElementWithRemedialActions, linkedContingencyWithRemedialActions, cnecCreationContexts);
cnecStatusMap.forEach((cnecId, cnecStatus) -> {
if (cnecStatus.isValid()) {
Cnec<?> cnec = crac.getCnec(cnecId);
if (isOnConstraintInstantCoherent(cnec.getState().getInstant(), instant)) {
remedialActionAdder.newOnConstraintUsageRule()
.withInstant(instant.getId())
.withCnec(cnecId)
.withUsageMethod(getUsageMethod(instant))
.add();
}
} else {
alterations.add(cnecStatus.statusDetails());
}
});
return !linkedAssessedElementWithRemedialActions.isEmpty();
}
private boolean addOnContingencyStateUsageRules(String
remedialActionId, Set<ContingencyWithRemedialAction> linkedContingencyWithRemedialActions, RemedialActionAdder<?>
remedialActionAdder, List<String> alterations, Instant instant) {
Map<String, AssociationStatus> contingencyStatusMap = OnContingencyStateUsageRuleHelper.processContingenciesLinkedToRemedialAction(crac, remedialActionId, linkedContingencyWithRemedialActions);
if (instant.isPreventive() && !linkedContingencyWithRemedialActions.isEmpty()) {
throw new OpenRaoImportException(ImportStatus.INCONSISTENCY_IN_DATA, "Remedial action %s will not be imported because it is linked to a contingency but is not curative".formatted(remedialActionId));
}
contingencyStatusMap.forEach((contingencyId, contingencyStatus) -> {
if (contingencyStatus.isValid()) {
remedialActionAdder.newOnContingencyStateUsageRule()
.withInstant(instant.getId())
.withContingency(contingencyId)
.withUsageMethod(getUsageMethod(instant))
.add();
} else {
alterations.add(contingencyStatus.statusDetails());
}
});
return !linkedContingencyWithRemedialActions.isEmpty();
}
private void addOnInstantUsageRules(String remedialActionId, RemedialActionAdder<?> remedialActionAdder, Instant instant) {
if (instant.isAuto()) {
throw new OpenRaoImportException(ImportStatus.INCONSISTENCY_IN_DATA, "Remedial action %s will not be imported because no contingency or assessed element is linked to the remedial action and this is nor supported for ARAs".formatted(remedialActionId));
}
remedialActionAdder.newOnInstantUsageRule().withInstant(instant.getId()).withUsageMethod(UsageMethod.AVAILABLE).add();
}
private static boolean isOnConstraintInstantCoherent(Instant cnecInstant, Instant remedialInstant) {
return remedialInstant.isAuto() ? cnecInstant.isAuto() : !cnecInstant.comesBefore(remedialInstant);
}
private InstantKind getInstantKind(GridStateAlterationRemedialAction nativeRemedialAction) {
if (RemedialActionKind.PREVENTIVE.toString().equals(nativeRemedialAction.kind())) {
return InstantKind.PREVENTIVE;
}
if (!nativeRemedialAction.isManual()) {
return InstantKind.AUTO;
}
return InstantKind.CURATIVE;
}
private UsageMethod getUsageMethod(Instant instant) {
return instant.isAuto() ? UsageMethod.FORCED : UsageMethod.AVAILABLE;
}
private static void checkKind(GridStateAlterationRemedialAction nativeRemedialAction) {
if (!RemedialActionKind.CURATIVE.toString().equals(nativeRemedialAction.kind()) && !RemedialActionKind.PREVENTIVE.toString().equals(nativeRemedialAction.kind())) {
throw new OpenRaoImportException(ImportStatus.INCONSISTENCY_IN_DATA, String.format("Remedial action %s will not be imported because remedial action must be of curative or preventive kind", nativeRemedialAction.mrid()));
}
if (RemedialActionKind.PREVENTIVE.toString().equals(nativeRemedialAction.kind()) && !nativeRemedialAction.isManual()) {
throw new OpenRaoImportException(ImportStatus.NOT_YET_HANDLED_BY_OPEN_RAO, "OpenRAO does not support preventive automatons, remedial action %s will be ignored".formatted(nativeRemedialAction.mrid()));
}
}
private RemedialActionType getRemedialActionType(String remedialActionId, String elementaryActionsAggregatorId) {
RemedialActionType remedialActionType;
if (elementaryActionsHelper.getTopologyActions().containsKey(elementaryActionsAggregatorId)) {
remedialActionType = RemedialActionType.NETWORK_ACTION;
} else if (elementaryActionsHelper.getRotatingMachineActions().containsKey(elementaryActionsAggregatorId)) {
remedialActionType = RemedialActionType.NETWORK_ACTION;
} else if (elementaryActionsHelper.getShuntCompensatorModifications().containsKey(elementaryActionsAggregatorId)) {
remedialActionType = RemedialActionType.NETWORK_ACTION;
} else if (elementaryActionsHelper.getTapPositionActions().containsKey(elementaryActionsAggregatorId)) {
// StaticPropertyRanges not mandatory in case of tapPositionsActions
remedialActionType = RemedialActionType.PST_RANGE_ACTION;
} else {
throw new OpenRaoImportException(ImportStatus.NOT_FOR_RAO, String.format("Remedial action %s will not be imported because it has no elementary action", remedialActionId));
}
return remedialActionType;
}
enum RemedialActionType {
PST_RANGE_ACTION,
NETWORK_ACTION
}
private Set<String> createRemedialActionGroups() {
Set<String> standaloneRasImplicatedIntoAGroup = new HashSet<>();
Map<String, Set<RemedialActionDependency>> remedialActionDependenciesByGroup = elementaryActionsHelper.getNativeRemedialActionDependencyPerNativeRemedialActionGroup();
elementaryActionsHelper.getRemedialActionGroupsPropertyBags().forEach(remedialActionGroup -> {
String groupName = remedialActionGroup.name() == null ? remedialActionGroup.mrid() : remedialActionGroup.name();
try {
Set<RemedialActionDependency> dependingEnabledRemedialActions = remedialActionDependenciesByGroup.getOrDefault(remedialActionGroup.mrid(), Set.of()).stream().filter(RemedialActionDependency::normalEnabled).collect(Collectors.toSet());
if (!dependingEnabledRemedialActions.isEmpty()) {
RemedialActionDependency refRemedialActionDependency = dependingEnabledRemedialActions.iterator().next();
if (!dependingEnabledRemedialActions.stream().allMatch(raDependency -> refRemedialActionDependency.kind().equals(raDependency.kind()))) {
standaloneRasImplicatedIntoAGroup.addAll(dependingEnabledRemedialActions.stream().map(RemedialActionDependency::remedialAction).collect(Collectors.toSet()));
throw new OpenRaoImportException(ImportStatus.INCONSISTENCY_IN_DATA, String.format("Remedial action group %s will not be imported because all related RemedialActionDependency must be of the same kind. All RA's depending in that group will be ignored: %s", remedialActionGroup.mrid(), printRaIds(dependingEnabledRemedialActions)));
}
NetworkAction refNetworkAction = crac.getNetworkAction(refRemedialActionDependency.remedialAction());
if (refNetworkAction == null) {
standaloneRasImplicatedIntoAGroup.addAll(dependingEnabledRemedialActions.stream().map(RemedialActionDependency::remedialAction).collect(Collectors.toSet()));
throw new OpenRaoImportException(ImportStatus.INCONSISTENCY_IN_DATA, String.format("Remedial action group %s will not be imported because the remedial action %s does not exist or not imported. All RA's depending in that group will be ignored: %s", remedialActionGroup.mrid(), refRemedialActionDependency.remedialAction(), printRaIds(dependingEnabledRemedialActions)));
}
List<UsageRule> onConstraintUsageRules = refNetworkAction.getUsageRules().stream().filter(OnConstraint.class::isInstance).toList();
List<UsageRule> onContingencyStateUsageRules = refNetworkAction.getUsageRules().stream().filter(OnContingencyState.class::isInstance).toList();
List<UsageRule> onInstantUsageRules = refNetworkAction.getUsageRules().stream().filter(OnInstant.class::isInstance).toList();
List<Action> elementaryActions = new ArrayList<>();
Set<String> operators = new HashSet<>();
dependingEnabledRemedialActions.forEach(remedialActionDependency -> {
if (crac.getNetworkAction(remedialActionDependency.remedialAction()) == null) {
standaloneRasImplicatedIntoAGroup.addAll(dependingEnabledRemedialActions.stream().map(RemedialActionDependency::remedialAction).collect(Collectors.toSet()));
throw new OpenRaoImportException(ImportStatus.INCONSISTENCY_IN_DATA, String.format("Remedial action group %s will not be imported because the remedial action %s does not exist or not imported. All RA's depending in that group will be ignored: %s", remedialActionGroup.mrid(), remedialActionDependency.remedialAction(), printRaIds(dependingEnabledRemedialActions)));
}
if (!refNetworkAction.getUsageRules().equals(crac.getNetworkAction(remedialActionDependency.remedialAction()).getUsageRules())) {
standaloneRasImplicatedIntoAGroup.addAll(dependingEnabledRemedialActions.stream().map(RemedialActionDependency::remedialAction).collect(Collectors.toSet()));
throw new OpenRaoImportException(ImportStatus.INCONSISTENCY_IN_DATA, String.format("Remedial action group %s will not be imported because all depending remedial actions must have the same usage rules. All RA's depending in that group will be ignored: %s", remedialActionGroup.mrid(), printRaIds(dependingEnabledRemedialActions)));
}
elementaryActions.addAll(crac.getNetworkAction(remedialActionDependency.remedialAction()).getElementaryActions());
operators.add(crac.getNetworkAction(remedialActionDependency.remedialAction()).getOperator());
});
NetworkActionAdder networkActionAdder = crac.newNetworkAction().withId(remedialActionGroup.mrid()).withName(groupName);
if (operators.size() == 1) {
networkActionAdder.withOperator(operators.iterator().next());
}
addUsageRulesToGroup(onConstraintUsageRules, onContingencyStateUsageRules, onInstantUsageRules, networkActionAdder);
addElementaryActionsToGroup(elementaryActions, networkActionAdder);
networkActionAdder.add();
contextByRaId.put(remedialActionGroup.mrid(), StandardElementaryCreationContext.imported(remedialActionGroup.mrid(), null, remedialActionGroup.mrid(), true, "The RemedialActionGroup with mRID " + remedialActionGroup.mrid() + " was turned into a remedial action from the following remedial actions: " + printRaIds(dependingEnabledRemedialActions)));
standaloneRasImplicatedIntoAGroup.addAll(dependingEnabledRemedialActions.stream().map(RemedialActionDependency::remedialAction).collect(Collectors.toSet()));
}
} catch (OpenRaoImportException e) {
contextByRaId.put(remedialActionGroup.mrid(), StandardElementaryCreationContext.notImported(remedialActionGroup.mrid(), null, e.getImportStatus(), e.getMessage()));
}
});
return standaloneRasImplicatedIntoAGroup;
}
private static void addElementaryActionsToGroup(List<Action> elementaryActions, NetworkActionAdder networkActionAdder) {
elementaryActions.forEach(ea -> {
if (ea instanceof GeneratorAction generatorAction) {
networkActionAdder.newGeneratorAction()
.withNetworkElement(generatorAction.getGeneratorId())
.withActivePowerValue(generatorAction.getActivePowerValue().getAsDouble())
.add();
} else if (ea instanceof LoadAction loadAction) {
networkActionAdder.newLoadAction()
.withNetworkElement(loadAction.getLoadId())
.withActivePowerValue(loadAction.getActivePowerValue().getAsDouble())
.add();
} else if (ea instanceof ShuntCompensatorPositionAction shuntCompensatorPositionAction) {
networkActionAdder.newShuntCompensatorPositionAction()
.withNetworkElement(shuntCompensatorPositionAction.getShuntCompensatorId())
.withSectionCount(shuntCompensatorPositionAction.getSectionCount())
.add();
} else if (ea instanceof SwitchAction switchAction) {
networkActionAdder.newSwitchAction()
.withNetworkElement(switchAction.getSwitchId())
.withActionType(switchAction.isOpen() ? ActionType.OPEN : ActionType.CLOSE)
.add();
}
});
}
private static void addUsageRulesToGroup(List<UsageRule> onConstraintUsageRules, List<UsageRule> onContingencyStateUsageRules, List<UsageRule> onInstantUsageRules, NetworkActionAdder networkActionAdder) {
onConstraintUsageRules.forEach(ur -> {
OnConstraint<?> onConstraintUsageRule = (OnConstraint<?>) ur;
networkActionAdder.newOnConstraintUsageRule()
.withInstant(onConstraintUsageRule.getInstant().getId())
.withUsageMethod(onConstraintUsageRule.getUsageMethod())
.withCnec(onConstraintUsageRule.getCnec().getId())
.add();
});
onContingencyStateUsageRules.forEach(ur -> {
OnContingencyState onContingencyStateUsageRule = (OnContingencyState) ur;
networkActionAdder.newOnContingencyStateUsageRule()
.withInstant(onContingencyStateUsageRule.getInstant().getId())
.withUsageMethod(onContingencyStateUsageRule.getUsageMethod())
.withContingency(onContingencyStateUsageRule.getContingency().getId())
.add();
});
onInstantUsageRules.forEach(ur -> {
OnInstant onInstantUsageRule = (OnInstant) ur;
networkActionAdder.newOnInstantUsageRule()
.withInstant(onInstantUsageRule.getInstant().getId())
.withUsageMethod(onInstantUsageRule.getUsageMethod())
.add();
});
}
private static String printRaIds(Set<RemedialActionDependency> dependingEnabledRemedialActions) {
return dependingEnabledRemedialActions.stream().map(RemedialActionDependency::remedialAction).sorted(String::compareTo).collect(Collectors.joining(", "));
}
}