Reports.java
/*
* Copyright (c) 2022-2025, 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.openloadflow.util;
import com.powsybl.commons.report.ReportNode;
import com.powsybl.commons.report.TypedValue;
import com.powsybl.openloadflow.OpenLoadFlowReportConstants;
import com.powsybl.openloadflow.network.LfBus;
import com.powsybl.openloadflow.util.report.PowsyblOpenLoadFlowReportResourceBundle;
import org.slf4j.Logger;
import java.util.List;
import java.util.Map;
/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public final class Reports {
public static final String NETWORK_NUM_CC = "networkNumCc";
public static final String NETWORK_NUM_SC = "networkNumSc";
private static final String ITERATION = "iteration";
private static final String ITERATION_COUNT = "iterationCount";
private static final String NETWORK_ID = "networkId";
private static final String IMPACTED_GENERATOR_COUNT = "impactedGeneratorCount";
private static final String IMPACTED_TRANSFORMER_COUNT = "impactedTransformerCount";
private static final String IMPACTED_SHUNT_COUNT = "impactedShuntCount";
private static final String BUS_ID = "busId";
private static final String GENERATORS_ID = "generatorIds";
private static final String CONTROLLER_BUS_ID = "controllerBusId";
private static final String CONTROLLED_BUS_ID = "controlledBusId";
private static final String ACTION_ID = "actionId";
private static final String CONTINGENCY_ID = "contingencyId";
public static final String MISMATCH = "mismatch";
public static final String LF_NETWORK_KEY = "olf.lfNetwork";
public static final String POST_CONTINGENCY_SIMULATION_KEY = "olf.postContingencySimulation";
public record BusReport(String busId, double mismatch, double nominalV, double v, double phi, double p, double q) {
}
private Reports() {
}
public static void reportNetworkSize(ReportNode reportNode, int busCount, int branchCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.networkSize")
.withUntypedValue("busCount", busCount)
.withUntypedValue("branchCount", branchCount)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportNetworkBalance(ReportNode reportNode, double activeGeneration, double activeLoad, double reactiveGeneration, double reactiveLoad) {
reportNode.newReportNode()
.withMessageTemplate("olf.networkBalance")
.withUntypedValue("activeGeneration", activeGeneration)
.withUntypedValue("activeLoad", activeLoad)
.withUntypedValue("reactiveGeneration", reactiveGeneration)
.withUntypedValue("reactiveLoad", reactiveLoad)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportNotUniqueControlledBusKeepingFirstControl(ReportNode reportNode, String generatorIds, String controllerBusId, String controlledBusId, String controlledBusGenId) {
reportNode.newReportNode()
.withMessageTemplate("olf.notUniqueControlledBusKeepingFirstControl")
.withUntypedValue(GENERATORS_ID, generatorIds)
.withUntypedValue(CONTROLLER_BUS_ID, controllerBusId)
.withUntypedValue(CONTROLLED_BUS_ID, controlledBusId)
.withUntypedValue("controlledBusGenId", controlledBusGenId)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportNotUniqueControlledBusDisablingControl(ReportNode reportNode, String generatorIds, String controllerBusId, String controlledBusId, String controlledBusGenId) {
reportNode.newReportNode()
.withMessageTemplate("olf.notUniqueControlledBusDisablingControl")
.withUntypedValue(GENERATORS_ID, generatorIds)
.withUntypedValue(CONTROLLER_BUS_ID, controllerBusId)
.withUntypedValue(CONTROLLED_BUS_ID, controlledBusId)
.withUntypedValue("controlledBusGenId", controlledBusGenId)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportNotUniqueTargetVControllerBusKeepingFirstControl(ReportNode reportNode, String generatorIds, String controllerBusId, Double keptTargetV, Double rejectedTargetV) {
reportNode.newReportNode()
.withMessageTemplate("olf.notUniqueTargetVControllerBusKeepingFirstControl")
.withUntypedValue(GENERATORS_ID, generatorIds)
.withUntypedValue(CONTROLLER_BUS_ID, controllerBusId)
.withUntypedValue("keptTargetV", keptTargetV)
.withUntypedValue("rejectedTargetV", rejectedTargetV)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportNotUniqueTargetVControllerBusDisablingControl(ReportNode reportNode, String generatorIds, String controllerBusId, Double targetV1, Double targetV2) {
reportNode.newReportNode()
.withMessageTemplate("olf.notUniqueTargetVControllerBusDisablingControl")
.withUntypedValue(GENERATORS_ID, generatorIds)
.withUntypedValue(CONTROLLER_BUS_ID, controllerBusId)
.withUntypedValue("targetV1", targetV1)
.withUntypedValue("targetV2", targetV2)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportControllerShuntAlreadyInVoltageControl(ReportNode reportNode, String controllerShuntId, String controlledBusId) {
reportNode.newReportNode()
.withMessageTemplate("olf.controllerShuntAlreadyInVoltageControl")
.withUntypedValue("controllerShuntId", controllerShuntId)
.withUntypedValue(CONTROLLED_BUS_ID, controlledBusId)
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}
public static void reportBusAlreadyControlledWithDifferentTargetV(ReportNode reportNode, String controllerBusId, String controlledBusId, String busesId, Double keptTargetV, Double ignoredTargetV) {
reportNode.newReportNode()
.withMessageTemplate("olf.busAlreadyControlledWithDifferentTargetV")
.withUntypedValue(CONTROLLER_BUS_ID, controllerBusId)
.withUntypedValue(CONTROLLED_BUS_ID, controlledBusId)
.withUntypedValue("busesId", busesId)
.withUntypedValue("keptTargetV", keptTargetV)
.withUntypedValue("ignoredTargetV", ignoredTargetV)
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}
public static void reportBranchControlledAtBothSides(ReportNode reportNode, String controlledBranchId, String keptSide, String rejectedSide) {
reportNode.newReportNode()
.withMessageTemplate("olf.branchControlledAtBothSides")
.withUntypedValue("controlledBranchId", controlledBranchId)
.withUntypedValue("keptSide", keptSide)
.withUntypedValue("rejectedSide", rejectedSide)
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}
public static void reportNetworkMustHaveAtLeastOneBusGeneratorVoltageControlEnabled(ReportNode reportNode) {
reportNode.newReportNode()
.withMessageTemplate("olf.networkMustHaveAtLeastOneBusGeneratorVoltageControlEnabled")
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportComponentsWithoutGenerators(ReportNode reportNode, int deadComponentsCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.componentsWithoutGenerators")
.withUntypedValue("deadComponentsCount", deadComponentsCount)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportMismatchDistributionFailure(ReportNode reportNode, double remainingMismatch) {
reportNode.newReportNode()
.withMessageTemplate("olf.mismatchDistributionFailure")
.withTypedValue(MISMATCH, remainingMismatch, OpenLoadFlowReportConstants.MISMATCH_TYPED_VALUE)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportResidualDistributionMismatch(ReportNode reportNode, double remainingMismatch) {
reportNode.newReportNode()
.withMessageTemplate("olf.residualDistributionMismatch")
.withTypedValue(MISMATCH, remainingMismatch, OpenLoadFlowReportConstants.MISMATCH_TYPED_VALUE)
.withSeverity(TypedValue.DEBUG_SEVERITY)
.add();
}
public static void reportMismatchDistributionSuccess(ReportNode reportNode, double slackBusActivePowerMismatch, int iterationCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.mismatchDistributionSuccess")
.withTypedValue("initialMismatch", slackBusActivePowerMismatch, OpenLoadFlowReportConstants.MISMATCH_TYPED_VALUE)
.withUntypedValue(ITERATION_COUNT, iterationCount)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportAreaNoInterchangeControl(ReportNode reportNode, String area, String reason) {
reportNode.newReportNode()
.withMessageTemplate("olf.areaNoInterchangeControl")
.withUntypedValue("area", area)
.withUntypedValue("reason", reason)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static ReportNode reportAreaInterchangeControlDistributionFailure(ReportNode reportNode) {
return reportNode.newReportNode()
.withMessageTemplate("olf.areaInterchangeControlDistributionFailure")
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportAreaInterchangeControlAreaMismatch(ReportNode reportNode, String area, double mismatch) {
reportNode.newReportNode()
.withMessageTemplate("olf.areaInterchangeControlAreaMismatch")
.withUntypedValue("area", area)
.withTypedValue(MISMATCH, mismatch, OpenLoadFlowReportConstants.MISMATCH_TYPED_VALUE)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportAreaInterchangeControlAreaDistributionSuccess(ReportNode reportNode, String area, double mismatch, int iterationCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.areaInterchangeControlAreaDistributionSuccess")
.withUntypedValue("area", area)
.withTypedValue(MISMATCH, mismatch, OpenLoadFlowReportConstants.MISMATCH_TYPED_VALUE)
.withUntypedValue(ITERATION_COUNT, iterationCount)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static ReportNode reportPvToPqBuses(ReportNode reportNode, int pvToPqBusCount, int remainingPvBusCount) {
return reportNode.newReportNode()
.withMessageTemplate("olf.pvToPqBuses")
.withUntypedValue("pvToPqBusCount", pvToPqBusCount)
.withUntypedValue("remainingPvBusCount", remainingPvBusCount)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportPvToPqMaxQ(ReportNode reportNode,
LfBus controllerBus,
double busQ,
double maxQ,
boolean log,
Logger logger) {
ReportNode newNode = reportNode.newReportNode()
.withMessageTemplate("olf.pvToPqMaxQ")
.withUntypedValue(BUS_ID, controllerBus.getId())
.withTypedValue("busQ", busQ * PerUnit.SB, TypedValue.REACTIVE_POWER)
.withTypedValue("maxQ", maxQ * PerUnit.SB, TypedValue.REACTIVE_POWER)
.withSeverity(TypedValue.TRACE_SEVERITY)
.add();
if (log) {
logger.trace(newNode.getMessage());
}
}
public static void reportPvToPqMinQ(ReportNode reportNode,
LfBus controllerBus,
double busQ,
double minQ,
boolean log,
Logger logger) {
ReportNode newNode = reportNode.newReportNode()
.withMessageTemplate("olf.PvToPqMinQ")
.withUntypedValue(BUS_ID, controllerBus.getId())
.withTypedValue("busQ", busQ * PerUnit.SB, TypedValue.REACTIVE_POWER)
.withTypedValue("minQ", minQ * PerUnit.SB, TypedValue.REACTIVE_POWER)
.withSeverity(TypedValue.TRACE_SEVERITY)
.add();
if (log) {
logger.trace(newNode.getMessage());
}
}
public static void reportPvToPqMinRealisticV(ReportNode reportNode,
LfBus controllerBus,
double targetQ,
double minRealisticV,
boolean log,
Logger logger) {
ReportNode newNode = reportNode.newReportNode()
.withMessageTemplate("olf.PvToPqMinRealisticV")
.withUntypedValue(BUS_ID, controllerBus.getId())
.withTypedValue("targetQ", targetQ * PerUnit.SB, TypedValue.REACTIVE_POWER)
.withTypedValue("minRealisticV", minRealisticV * controllerBus.getNominalV(), TypedValue.VOLTAGE)
.withSeverity(TypedValue.TRACE_SEVERITY)
.add();
if (log) {
logger.trace(newNode.getMessage());
}
}
public static void reportPvToPqMaxRealisticV(ReportNode reportNode,
LfBus controllerBus,
double targetQ,
double maxRealisticV,
boolean log,
Logger logger) {
ReportNode newNode = reportNode.newReportNode()
.withMessageTemplate("olf.PvToPqMaxRealisticV")
.withUntypedValue("busId", controllerBus.getId())
.withTypedValue("targetQ", targetQ * PerUnit.SB, TypedValue.REACTIVE_POWER)
.withTypedValue("maxRealisticV", maxRealisticV * controllerBus.getNominalV(), TypedValue.VOLTAGE)
.withSeverity(TypedValue.TRACE_SEVERITY)
.add();
if (log) {
logger.trace(newNode.getMessage());
}
}
public static ReportNode reportPqToPvBuses(ReportNode reportNode, int pqToPvBusCount, int blockedPqBusCount) {
return reportNode.newReportNode()
.withMessageTemplate("olf.PqToPvBuses")
.withUntypedValue("pqToPvBusCount", pqToPvBusCount)
.withUntypedValue("blockedPqBusCount", blockedPqBusCount)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static ReportNode createRootReportPvPqSwitchLimit(ReportNode firstRootReportNode, LfBus controllerBus, int limit, boolean log, Logger logger) {
ReportNode result = ReportNode.newRootReportNode()
.withLocale(firstRootReportNode.getTreeContext().getLocale())
.withResourceBundles(PowsyblOpenLoadFlowReportResourceBundle.BASE_NAME)
.withMessageTemplate("olf.pvPqSwitchLimit")
.withUntypedValue("busId", controllerBus.getId())
.withUntypedValue("limit", limit)
.withSeverity(TypedValue.TRACE_SEVERITY)
.build();
if (log) {
logger.trace(result.getMessage());
}
return result;
}
public static ReportNode createRootReportPqToPvBusMaxLimit(ReportNode firstRootReportNode, LfBus controllerBus, LfBus controlledBus, double targetV, boolean log, Logger logger) {
ReportNode result = ReportNode.newRootReportNode()
.withLocale(firstRootReportNode.getTreeContext().getLocale())
.withResourceBundles(PowsyblOpenLoadFlowReportResourceBundle.BASE_NAME)
.withMessageTemplate("olf.pqToPvBusMaxLimit")
.withUntypedValue("busId", controllerBus.getId())
// busV and targetV need a higher precision than usual Voltage rounding to understand
// the difference. Their unit is not given to avoid a too high formatting based on Unit
.withUntypedValue("busV", controlledBus.getV() * controlledBus.getNominalV())
.withUntypedValue("targetV", targetV * controlledBus.getNominalV())
.withSeverity(TypedValue.TRACE_SEVERITY)
.build();
if (log) {
logger.trace(result.getMessage());
}
return result;
}
public static ReportNode createRootReportPqToPvBusMinLimit(ReportNode firstRootReportNode, LfBus controllerBus, LfBus controlledBus, double targetV, boolean log, Logger logger) {
ReportNode result = ReportNode.newRootReportNode()
.withLocale(firstRootReportNode.getTreeContext().getLocale())
.withResourceBundles(PowsyblOpenLoadFlowReportResourceBundle.BASE_NAME)
.withMessageTemplate("olf.pqToPvBusMinLimit")
.withUntypedValue("busId", controllerBus.getId())
// busV and targetV need a higher precision than usual Voltage rounding to understand
// the difference. Their unit is not given to avoid a too high formatting based on Unit
.withUntypedValue("busV", controlledBus.getV() * controlledBus.getNominalV())
.withUntypedValue("targetV", targetV * controlledBus.getNominalV())
.withSeverity(TypedValue.TRACE_SEVERITY)
.build();
if (log) {
logger.trace(result.getMessage());
}
return result;
}
public static void reportBusForcedToBePv(ReportNode reportNode, String busId) {
reportNode.newReportNode()
.withMessageTemplate("olf.busForcedToBePv")
.withUntypedValue(BUS_ID, busId)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportBusesWithUpdatedQLimits(ReportNode reportNode, int numBusesWithUpdatedQLimits) {
reportNode.newReportNode()
.withMessageTemplate("olf.busWithUpdatedQLimits")
.withUntypedValue("numBusesWithUpdatedQLimits", numBusesWithUpdatedQLimits)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static ReportNode reportReactiveControllerBusesToPqBuses(ReportNode reportNode, int remoteReactivePowerControllerBusToPqCount) {
return reportNode.newReportNode()
.withMessageTemplate("olf.reactiveControllerBusesToPqBuses")
.withUntypedValue("remoteReactivePowerControllerBusToPqCount", remoteReactivePowerControllerBusToPqCount)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static ReportNode createRootReportReactiveControllerBusesToPqMaxQ(ReportNode firstRootReportNode,
LfBus controllerBus,
double busQ,
double maxQ,
boolean log,
Logger logger) {
ReportNode result = ReportNode.newRootReportNode()
.withLocale(firstRootReportNode.getTreeContext().getLocale())
.withResourceBundles(PowsyblOpenLoadFlowReportResourceBundle.BASE_NAME)
.withMessageTemplate("olf.reactiveControllerBusesToPqMaxQ")
.withUntypedValue("busId", controllerBus.getId())
.withTypedValue("busQ", busQ * PerUnit.SB, TypedValue.REACTIVE_POWER)
.withTypedValue("maxQ", maxQ * PerUnit.SB, TypedValue.REACTIVE_POWER)
.withSeverity(TypedValue.TRACE_SEVERITY)
.build();
if (log) {
logger.trace(result.getMessage());
}
return result;
}
public static ReportNode createRootReportReactiveControllerBusesToPqMinQ(ReportNode firstRootReportNode,
LfBus controllerBus,
double busQ,
double minQ,
boolean log,
Logger logger) {
ReportNode result = ReportNode.newRootReportNode()
.withLocale(firstRootReportNode.getTreeContext().getLocale())
.withResourceBundles(PowsyblOpenLoadFlowReportResourceBundle.BASE_NAME)
.withMessageTemplate("olf.reactiveControllerBusesToPqMinQ")
.withUntypedValue("busId", controllerBus.getId())
.withTypedValue("busQ", busQ * PerUnit.SB, TypedValue.REACTIVE_POWER)
.withTypedValue("minQ", minQ * PerUnit.SB, TypedValue.REACTIVE_POWER)
.withSeverity(TypedValue.TRACE_SEVERITY)
.build();
if (log) {
logger.trace(result.getMessage());
}
return result;
}
public static void reportStandByAutomatonActivation(ReportNode reportNode, String busId, double newTargetV) {
reportNode.newReportNode()
.withMessageTemplate("olf.standByAutomatonActivation")
.withUntypedValue(BUS_ID, busId)
.withUntypedValue("newTargetV", newTargetV)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportCurrentLimiterPstsChangedTaps(ReportNode reportNode, int numOfCurrentLimiterPstsThatChangedTap) {
reportNode.newReportNode()
.withMessageTemplate("olf.currentLimiterPstsChangedTaps")
.withUntypedValue("numOfCurrentLimiterPstsThatChangedTap", numOfCurrentLimiterPstsThatChangedTap)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportActivePowerControlPstsChangedTaps(ReportNode reportNode, int numOfActivePowerControlPstsThatChangedTap) {
reportNode.newReportNode()
.withMessageTemplate("olf.activePowerControlPstsChangedTaps")
.withUntypedValue("numOfActivePowerControlPstsThatChangedTap", numOfActivePowerControlPstsThatChangedTap)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportTransformerControlAlreadyExistsWithDifferentTargetV(ReportNode reportNode, String firstControllerId, String newControllerId, String controlledBusId, double vcTargetValue, double targetValue) {
reportNode.newReportNode()
.withMessageTemplate("olf.transformerControlAlreadyExistsWithDifferentTargetV")
.withUntypedValue(CONTROLLED_BUS_ID, controlledBusId)
.withUntypedValue("firstControllerId", firstControllerId)
.withUntypedValue("newControllerId", newControllerId)
.withUntypedValue("vcTargetValue", vcTargetValue)
.withUntypedValue("targetValue", targetValue)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportTransformerControlAlreadyExistsUpdateDeadband(ReportNode reportNode, String firstControllerId, String newControllerId, String controlledBusId, double newTargetDeadband, Double oldTargetDeadband) {
reportNode.newReportNode()
.withMessageTemplate("olf.transformerControlAlreadyExistsUpdateDeadband")
.withUntypedValue(CONTROLLED_BUS_ID, controlledBusId)
.withUntypedValue("firstControllerId", firstControllerId)
.withUntypedValue("newControllerId", newControllerId)
.withUntypedValue("newTargetDeadband", newTargetDeadband)
.withUntypedValue("oldTargetDeadband", oldTargetDeadband == null ? "---" : oldTargetDeadband.toString())
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportTransformerControlBusesOutsideDeadband(ReportNode reportNode, int numTransformerControlBusesOutsideDeadband) {
reportNode.newReportNode()
.withMessageTemplate("olf.transformerControlBusesOutsideDeadband")
.withUntypedValue("numTransformerControlBusesOutsideDeadband", numTransformerControlBusesOutsideDeadband)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportTransformerControlBranchesOutsideDeadband(ReportNode reportNode, int numTransformerControlBranchesOutsideDeadband) {
reportNode.newReportNode()
.withMessageTemplate("olf.transformerControlBranchesOutsideDeadband")
.withUntypedValue("numTransformerControlBranchesOutsideDeadband", numTransformerControlBranchesOutsideDeadband)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportTransformerControlChangedTaps(ReportNode reportNode, int numTransformerControlAdjusted) {
reportNode.newReportNode()
.withMessageTemplate("olf.transformerControlChangedTaps")
.withUntypedValue("numTransformerControlAdjusted", numTransformerControlAdjusted)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportTransformerControlTapLimit(ReportNode reportNode, int numTransformerControlTapLimit) {
reportNode.newReportNode()
.withMessageTemplate("olf.transformerControlTapLimit")
.withUntypedValue("numTransformerControlTapLimit", numTransformerControlTapLimit)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportShuntVoltageControlChangedSection(ReportNode reportNode, int numShuntVoltageControlAdjusted) {
reportNode.newReportNode()
.withMessageTemplate("olf.shuntVoltageControlChangedSection")
.withUntypedValue("numShuntVoltageControlAdjusted", numShuntVoltageControlAdjusted)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportUnsuccessfulOuterLoop(ReportNode reportNode, String outerLoopStatus) {
reportNode.newReportNode()
.withMessageTemplate("olf.outerLoopStatus")
.withUntypedValue("outerLoopStatus", outerLoopStatus)
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}
public static void reportMaxOuterLoopIterations(ReportNode reportNode, int iterationCount, boolean withLog, Logger logger) {
ReportNode added = reportNode.newReportNode()
.withMessageTemplate("olf.maxOuterLoopIterations")
.withUntypedValue("outerLoopIterationCount", iterationCount)
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
if (withLog) {
logger.error(added.getMessage());
}
}
public static void reportDcLfSolverFailure(ReportNode reportNode, String errorMessage) {
reportNode.newReportNode()
.withMessageTemplate("olf.dcLfFailure")
.withUntypedValue("errorMessage", errorMessage)
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}
public static void reportDcLfComplete(ReportNode reportNode, boolean succeeded, String outerloopStatus) {
reportNode.newReportNode()
.withMessageTemplate("olf.dcLfComplete")
.withUntypedValue("succeeded", succeeded)
.withUntypedValue("outerloopStatus", outerloopStatus)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportGeneratorsDiscardedFromVoltageControlBecauseNotStarted(ReportNode reportNode, int impactedGeneratorCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.generatorsDiscardedFromVoltageControlBecauseNotStarted")
.withUntypedValue(IMPACTED_GENERATOR_COUNT, impactedGeneratorCount)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportGeneratorsDiscardedFromVoltageControlBecauseReactiveRangeIsTooSmall(ReportNode reportNode, int impactedGeneratorCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.generatorsDiscardedFromVoltageControlBecauseReactiveRangeIsTooSmall")
.withUntypedValue(IMPACTED_GENERATOR_COUNT, impactedGeneratorCount)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportGeneratorsDiscardedFromVoltageControlBecauseTargetPIsOutsideActiveLimits(ReportNode reportNode, int impactedGeneratorCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.generatorsDiscardedFromVoltageControlBecauseTargetPIsOutsideActiveLimits")
.withUntypedValue(IMPACTED_GENERATOR_COUNT, impactedGeneratorCount)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportGeneratorsDiscardedFromVoltageControlBecauseTargetVIsImplausible(ReportNode reportNode, int impactedGeneratorCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.generatorsDiscardedFromVoltageControlBecauseTargetVIsImplausible")
.withUntypedValue(IMPACTED_GENERATOR_COUNT, impactedGeneratorCount)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportGeneratorsDiscardedFromVoltageControlBecauseInconsistentControlledBus(ReportNode reportNode, int impactedGeneratorCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.generatorsDiscardedFromVoltageControlBecauseInconsistentControlledBus")
.withUntypedValue(IMPACTED_GENERATOR_COUNT, impactedGeneratorCount)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportGeneratorsDiscardedFromVoltageControlBecauseInconsistentTargetVoltages(ReportNode reportNode, int impactedGeneratorCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.generatorsDiscardedFromVoltageControlBecauseInconsistentTargetVoltages")
.withUntypedValue(IMPACTED_GENERATOR_COUNT, impactedGeneratorCount)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportTransformersDiscardedFromVoltageControlBecauseTargetVIsInconsistent(ReportNode reportNode, int impactedTransformerCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.transformersDiscardedFromVoltageControlBecauseTargetVIsInconsistent")
.withUntypedValue(IMPACTED_TRANSFORMER_COUNT, impactedTransformerCount)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportShuntsDiscardedFromVoltageControlBecauseTargetVIsInconsistent(ReportNode reportNode, int impactedShuntCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.shuntsDiscardedFromVoltageControlBecauseTargetVIsInconsistent")
.withUntypedValue(IMPACTED_SHUNT_COUNT, impactedShuntCount)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportAcLfComplete(ReportNode reportNode, boolean success, String solverStatus, String outerloopStatus) {
TypedValue severity = success ? TypedValue.INFO_SEVERITY : TypedValue.ERROR_SEVERITY;
String successText = success ? "successfully" : "with error";
reportNode.newReportNode()
.withMessageTemplate("olf.acLfComplete")
.withUntypedValue("successText", successText)
.withUntypedValue("solverStatus", solverStatus)
.withUntypedValue("outerloopStatus", outerloopStatus)
.withSeverity(severity)
.add();
}
public static ReportNode createLoadFlowReporter(ReportNode reportNode, String networkId) {
return reportNode.newReportNode().withMessageTemplate("olf.loadFlow")
.withUntypedValue(NETWORK_ID, networkId)
.add();
}
public static ReportNode createRootLfNetworkReportNode(ReportNode firstRootReportNode, int networkNumCc, int networkNumSc) {
return ReportNode.newRootReportNode()
.withLocale(firstRootReportNode.getTreeContext().getLocale())
.withAllResourceBundlesFromClasspath()
.withMessageTemplate(LF_NETWORK_KEY)
.withUntypedValue(NETWORK_NUM_CC, networkNumCc)
.withUntypedValue(NETWORK_NUM_SC, networkNumSc)
.build();
}
public static ReportNode includeLfNetworkReportNode(ReportNode reportNode, ReportNode lfNetworkReportNode) {
reportNode.include(lfNetworkReportNode);
return lfNetworkReportNode;
}
public static ReportNode createNetworkInfoReporter(ReportNode reportNode) {
return reportNode.newReportNode()
.withMessageTemplate("olf.networkInfo")
.add();
}
public static ReportNode createOuterLoopReporter(ReportNode reportNode, String outerLoopType) {
return reportNode.newReportNode()
.withMessageTemplate("olf.OuterLoop")
.withUntypedValue("outerLoopType", outerLoopType)
.add();
}
public static ReportNode createOuterLoopIterationReporter(ReportNode reportNode, int outerLoopIteration) {
return reportNode.newReportNode()
.withMessageTemplate("olf.OuterLoopIteration")
.withUntypedValue("outerLoopIteration", outerLoopIteration)
.add();
}
public static ReportNode createSensitivityAnalysis(ReportNode reportNode, String networkId) {
return reportNode.newReportNode()
.withMessageTemplate("olf.sensitivityAnalysis")
.withUntypedValue(NETWORK_ID, networkId)
.add();
}
public static ReportNode createAcSecurityAnalysis(ReportNode reportNode, String networkId) {
return reportNode.newReportNode()
.withMessageTemplate("olf.acSecurityAnalysis")
.withUntypedValue(NETWORK_ID, networkId)
.add();
}
public static ReportNode createDcSecurityAnalysis(ReportNode reportNode, String networkId) {
return reportNode.newReportNode()
.withMessageTemplate("olf.dcSecurityAnalysis")
.withUntypedValue(NETWORK_ID, networkId)
.add();
}
public static ReportNode createWoodburyDcSecurityAnalysis(ReportNode reportNode, String networkId) {
return reportNode.newReportNode()
.withMessageTemplate("olf.woodburyDcSecurityAnalysis")
.withUntypedValue(NETWORK_ID, networkId)
.add();
}
public static ReportNode createPreContingencySimulation(ReportNode reportNode) {
return reportNode.newReportNode()
.withMessageTemplate("olf.preContingencySimulation")
.add();
}
public static ReportNode createPostContingencySimulation(ReportNode reportNode, String contingencyId) {
return reportNode.newReportNode()
.withMessageTemplate(POST_CONTINGENCY_SIMULATION_KEY)
.withUntypedValue(CONTINGENCY_ID, contingencyId)
.add();
}
public static ReportNode createOperatorStrategySimulation(ReportNode reportNode, String operatorStrategyId) {
return reportNode.newReportNode()
.withMessageTemplate("olf.operatorStrategySimulation")
.withUntypedValue("operatorStrategyId", operatorStrategyId)
.add();
}
public static ReportNode createDetailedSolverReporter(ReportNode reportNode, String solverName, int networkNumCc, int networkNumSc) {
ReportNode subReportNode = createSolverReport(reportNode, solverName, networkNumCc, networkNumSc);
subReportNode.newReportNode()
.withMessageTemplate("olf.solverNoOuterLoops")
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
return subReportNode;
}
public static ReportNode createDetailedSolverReporterOuterLoop(ReportNode reportNode, String solverName, int networkNumCc, int networkNumSc,
int outerLoopIteration, String outerLoopType) {
ReportNode subReportNode = createSolverReport(reportNode, solverName, networkNumCc, networkNumSc);
subReportNode.newReportNode()
.withMessageTemplate("olf.solverOuterLoopCurrentType")
.withUntypedValue("outerLoopIteration", outerLoopIteration)
.withUntypedValue("outerLoopType", outerLoopType)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
return subReportNode;
}
public static ReportNode createSolverReport(ReportNode reportNode, String solverName, int networkNumCc, int networkNumSc) {
return reportNode.newReportNode()
.withMessageTemplate("olf.solver")
.withUntypedValue(NETWORK_NUM_CC, networkNumCc)
.withUntypedValue(NETWORK_NUM_SC, networkNumSc)
.withUntypedValue("solverName", solverName)
.add();
}
public static ReportNode createNewtonRaphsonMismatchReporter(ReportNode reportNode, int iteration) {
if (iteration == 0) {
return reportNode.newReportNode()
.withMessageTemplate("olf.mismatchInitial").
add();
} else {
return reportNode.newReportNode()
.withMessageTemplate("olf.mismatchIteration")
.withUntypedValue(ITERATION, iteration)
.add();
}
}
public static void reportNewtonRaphsonError(ReportNode reportNode, String error) {
reportNode.newReportNode()
.withMessageTemplate("olf.NRError")
.withUntypedValue("error", error)
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}
public static void reportNewtonRaphsonNorm(ReportNode reportNode, double norm) {
reportNode.newReportNode()
.withMessageTemplate("olf.NRNorm")
.withUntypedValue("norm", norm)
.withSeverity(TypedValue.TRACE_SEVERITY)
.add();
}
public static void reportNewtonRaphsonLargestMismatches(ReportNode reportNode, String acEquationType, BusReport busReport) {
String mismatchUnit;
double mismatchUnitConverter;
switch (acEquationType) {
case "P" -> {
mismatchUnit = "MW";
mismatchUnitConverter = PerUnit.SB;
}
case "Q" -> {
mismatchUnit = "MVar";
mismatchUnitConverter = PerUnit.SB;
}
default -> {
mismatchUnit = "p.u.";
mismatchUnitConverter = 1.0;
}
}
ReportNode subReportNode = reportNode.newReportNode()
.withMessageTemplate("olf.NRMismatch")
.withUntypedValue("equationType", acEquationType)
.withTypedValue(MISMATCH, mismatchUnitConverter * busReport.mismatch(), OpenLoadFlowReportConstants.MISMATCH_TYPED_VALUE)
.withUntypedValue("mismatchUnit", mismatchUnit)
.add();
subReportNode.newReportNode()
.withMessageTemplate("olf.NRMismatchBusInfo")
.withUntypedValue(BUS_ID, busReport.busId())
.withUntypedValue("busNominalV", busReport.nominalV())
.withSeverity(TypedValue.TRACE_SEVERITY)
.add();
subReportNode.newReportNode()
.withMessageTemplate("olf.NRMismatchBusV")
.withUntypedValue("busV", busReport.v())
.withUntypedValue("busPhi", busReport.phi())
.withSeverity(TypedValue.TRACE_SEVERITY)
.add();
subReportNode.newReportNode()
.withMessageTemplate("olf.NRMismatchBusInjection")
.withUntypedValue("busP", busReport.p())
.withUntypedValue("busQ", busReport.q())
.withSeverity(TypedValue.TRACE_SEVERITY)
.add();
}
public static void reportLineSearchStateVectorScaling(ReportNode reportNode, double stepSize) {
reportNode.newReportNode()
.withMessageTemplate("olf.lineSearchStateVectorScaling")
.withUntypedValue("stepSize", stepSize)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportMaxVoltageChangeStateVectorScaling(ReportNode reportNode, double stepSize, int vCutCount, int phiCutCount) {
reportNode.newReportNode()
.withMessageTemplate("olf.maxVoltageChangeStateVectorScaling")
.withUntypedValue("stepSize", stepSize)
.withUntypedValue("vCutCount", vCutCount)
.withUntypedValue("phiCutCount", phiCutCount)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportNewtonRaphsonBusesOutOfRealisticVoltageRange(ReportNode reportNode, Map<String, Double> busesOutOfRealisticVoltageRange, double minRealisticVoltage, double maxRealisticVoltage) {
ReportNode voltageOutOfRangeReport = reportNode.newReportNode()
.withMessageTemplate("olf.newtonRaphsonBusesOutOfRealisticVoltageRange")
.withUntypedValue("busCountOutOfRealisticVoltageRange", busesOutOfRealisticVoltageRange.size())
.withUntypedValue("minRealisticVoltage", minRealisticVoltage)
.withUntypedValue("maxRealisticVoltage", maxRealisticVoltage)
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
busesOutOfRealisticVoltageRange.forEach((id, voltage) -> voltageOutOfRangeReport.newReportNode()
.withMessageTemplate("olf.newtonRaphsonBusesOutOfRealisticVoltageRangeDetails")
.withUntypedValue(BUS_ID, id)
.withUntypedValue("voltage", voltage)
.withSeverity(TypedValue.TRACE_SEVERITY)
.add());
}
public static void reportAngleReferenceBusAndSlackBuses(ReportNode reportNode, String referenceBus, List<String> slackBuses) {
reportNode.newReportNode()
.withMessageTemplate("olf.angleReferenceBusSelection")
.withUntypedValue("referenceBus", referenceBus)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
slackBuses.forEach(slackBus -> reportNode.newReportNode()
.withMessageTemplate("olf.slackBusSelection")
.withUntypedValue("slackBus", slackBus)
.withSeverity(TypedValue.INFO_SEVERITY)
.add());
}
public static void reportAcEmulationDisabledInWoodburyDcSecurityAnalysis(ReportNode reportNode) {
reportNode.newReportNode()
.withMessageTemplate("olf.acEmulationDisabledInWoodburyDcSecurityAnalysis")
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
public static void reportContingencyActivePowerLossDistribution(ReportNode reportNode, double mismatch, double remaining) {
reportNode.newReportNode()
.withMessageTemplate("olf.contingencyActivePowerLossDistribution")
.withUntypedValue(MISMATCH, mismatch)
.withUntypedValue("distributed", mismatch - remaining)
.withUntypedValue("remaining", remaining)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}
public static void reportActionApplicationFailure(String actionId, String contingencyId, ReportNode node) {
node.newReportNode()
.withMessageTemplate("olf.LfActionUtils")
.withUntypedValue(ACTION_ID, actionId)
.withUntypedValue(CONTINGENCY_ID, contingencyId)
.add();
}
public static ReportNode createRootThreadReport(ReportNode firstRootReport) {
return ReportNode.newRootReportNode()
.withLocale(firstRootReport.getTreeContext().getLocale())
.withAllResourceBundlesFromClasspath()
.withMessageTemplate("olf.threadRoot")
.build();
}
}