Skip to content

ReportNode internationalization (I18n) #183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ public CompletableFuture<BalanceComputationResult> run(Network network, String w
ReportNode iterationReportNode = Reports.createBalanceComputationIterationReporter(reportNode, context.getIterationNum());
context.setIterationReportNode(iterationReportNode);
// Step 1: Perform the scaling
ReportNode scalingReportNode = iterationReportNode.newReportNode().withMessageTemplate("scaling", "Scaling").add();
ReportNode scalingReportNode = Reports.createScalingReporter(iterationReportNode);
context.getBalanceOffsets().forEach((area, offset) -> {
Scalable scalable = area.getScalable();
double done = scalable.scale(network, offset, parameters.getScalingParameters());
Reports.reportScaling(scalingReportNode, area.getName(), offset, done);
Reports.reportAreaScaling(scalingReportNode, area.getName(), offset, done);
LOGGER.info("Iteration={}, Scaling for area {}: offset={}, done={}", context.getIterationNum(), area.getName(), offset, done);
});

Expand All @@ -106,7 +106,7 @@ public CompletableFuture<BalanceComputationResult> run(Network network, String w
}

// Step 3: Compute balance and mismatch for each area
ReportNode mismatchReportNode = iterationReportNode.newReportNode().withMessageTemplate("mismatch", "Mismatch").add();
ReportNode mismatchReportNode = Reports.createMismatchReporter(iterationReportNode);
for (BalanceComputationArea area : areas) {
NetworkArea na = context.getNetworkArea(area);
double target = area.getTargetNetPosition();
Expand All @@ -128,7 +128,7 @@ public CompletableFuture<BalanceComputationResult> run(Network network, String w
}
} while (context.getIterationNum() < parameters.getMaxNumberIterations() && result.getStatus() != BalanceComputationResult.Status.SUCCESS);

ReportNode statusReportNode = reportNode.newReportNode().withMessageTemplate("status", "Status").add();
ReportNode statusReportNode = Reports.createStatusReporter(reportNode);
if (result.getStatus() == BalanceComputationResult.Status.SUCCESS) {
List<String> networkAreasName = areas.stream()
.map(BalanceComputationArea::getName).collect(Collectors.toList());
Expand Down Expand Up @@ -182,7 +182,7 @@ protected boolean isLoadFlowResultOk(BalanceComputationRunningContext context, f
return false;
}
final var cr = list.get(0);
ReportNode lfStatusReportNode = context.getIterationReportNode().newReportNode().withMessageTemplate("loadFlowStatus", "Checking load flow status").add();
ReportNode lfStatusReportNode = Reports.createLoadFlowStatusReporter(context.getIterationReportNode());
final var severity = cr.getStatus() == LoadFlowResult.ComponentResult.Status.CONVERGED ? TypedValue.INFO_SEVERITY : TypedValue.ERROR_SEVERITY;
Reports.reportLfStatus(lfStatusReportNode, cr.getConnectedComponentNum(), cr.getSynchronousComponentNum(), cr.getStatus().name(), severity);
return cr.getStatus() == LoadFlowResult.ComponentResult.Status.CONVERGED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public final class Reports {
private Reports() {
}

public static void reportScaling(ReportNode reportNode, String areaName, double offset, double done) {
reportNode.newReportNode().withMessageTemplate("areaScaling",
"Scaling for area ${areaName}: offset=${offset}, done=${done}")
public static void reportAreaScaling(ReportNode reportNode, String areaName, double offset, double done) {
reportNode.newReportNode()
.withMessageTemplate("entsoe.balances_adjustment.areaScaling", "Scaling for area ${areaName}: offset=${offset}, done=${done}")
.withUntypedValue(AREA_NAME, areaName)
.withUntypedValue("offset", offset)
.withUntypedValue("done", done)
Expand All @@ -34,8 +34,8 @@ public static void reportScaling(ReportNode reportNode, String areaName, double
}

public static void reportLfStatus(ReportNode reportNode, int networkNumCc, int networkNumSc, String status, TypedValue severity) {
reportNode.newReportNode().withMessageTemplate("lfStatus",
"Network CC${networkNumCc} SC${networkNumSc} Load flow complete with status '${status}'")
reportNode.newReportNode()
.withMessageTemplate("entsoe.balances_adjustment.lfStatus", "Network CC${networkNumCc} SC${networkNumSc} Load flow complete with status '${status}'")
.withUntypedValue("networkNumCc", networkNumCc)
.withUntypedValue("networkNumSc", networkNumSc)
.withUntypedValue("status", status)
Expand All @@ -44,8 +44,8 @@ public static void reportLfStatus(ReportNode reportNode, int networkNumCc, int n
}

public static void reportAreaMismatch(ReportNode reportNode, String areaName, double mismatch, double target, double balance) {
reportNode.newReportNode().withMessageTemplate("areaMismatch",
"Mismatch for area ${areaName}: ${mismatch} (target=${target}, balance=${balance})")
reportNode.newReportNode()
.withMessageTemplate("entsoe.balances_adjustment.areaMismatch", "Mismatch for area ${areaName}: ${mismatch} (target=${target}, balance=${balance})")
.withUntypedValue(AREA_NAME, areaName)
.withUntypedValue("mismatch", mismatch)
.withUntypedValue("target", target)
Expand All @@ -55,26 +55,52 @@ public static void reportAreaMismatch(ReportNode reportNode, String areaName, do
}

public static void reportBalancedAreas(ReportNode reportNode, List<String> networkAreasName, int iterationCount) {
reportNode.newReportNode().withMessageTemplate("balancedAreas",
"Areas ${networkAreasName} are balanced after ${iterationCount} iterations")
reportNode.newReportNode()
.withMessageTemplate("entsoe.balances_adjustment.balancedAreas", "Areas ${networkAreasName} are balanced after ${iterationCount} iterations")
.withUntypedValue("networkAreasName", networkAreasName.toString())
.withUntypedValue("iterationCount", iterationCount)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}

public static void reportUnbalancedAreas(ReportNode reportNode, int iteration, BigDecimal totalMismatch) {
reportNode.newReportNode().withMessageTemplate("unbalancedAreas",
"Areas are unbalanced after ${iteration} iterations, total mismatch is ${totalMismatch}")
reportNode.newReportNode()
.withMessageTemplate("entsoe.balances_adjustment.unbalancedAreas", "Areas are unbalanced after ${iteration} iterations, total mismatch is ${totalMismatch}")
.withUntypedValue(ITERATION, iteration)
.withUntypedValue("totalMismatch", totalMismatch.toString())
.withSeverity(TypedValue.ERROR_SEVERITY)
.add();
}

public static ReportNode createBalanceComputationIterationReporter(ReportNode reportNode, int iteration) {
return reportNode.newReportNode().withMessageTemplate("balanceComputation", "Balance Computation iteration '${iteration}'")
return reportNode.newReportNode()
.withMessageTemplate("entsoe.balances_adjustment.balanceComputation", "Balance Computation iteration '${iteration}'")
.withUntypedValue(ITERATION, iteration)
.add();
}

public static ReportNode createStatusReporter(ReportNode reportNode) {
return reportNode.newReportNode()
.withMessageTemplate("entsoe.balances_adjustment.status", "Status")
.add();
}

public static ReportNode createMismatchReporter(ReportNode iterationReportNode) {
return iterationReportNode.newReportNode()
.withMessageTemplate("entsoe.balances_adjustment.mismatch", "Mismatch")
.add();
}

public static ReportNode createScalingReporter(ReportNode iterationReportNode) {
return iterationReportNode.newReportNode()
.withMessageTemplate("entsoe.balances_adjustment.scaling", "Scaling")
.add();
}

public static ReportNode createLoadFlowStatusReporter(ReportNode reportNode) {
return reportNode.newReportNode()
.withMessageTemplate("entsoe.balances_adjustment.loadFlowStatus", "Checking load flow status")
.add();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Copyright (c) 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.glsk.commons;

import com.powsybl.commons.report.ReportNode;

import static com.powsybl.commons.report.TypedValue.WARN_SEVERITY;

/**
* @author Olivier Perrin {@literal <olivier.perrin at rte-france.com>}
*/
public final class GlskReports {

public static final String NODE_ID_KEY = "NodeId";
public static final String TYPE_KEY = "Type";
public static final String TSO_KEY = "TSO";

private GlskReports() {
}

public static void reportNodeNotFound(String nodeId, String type, String tso, ReportNode reportNode) {
reportNode.newReportNode()
.withMessageTemplate("entsoe.glsk.nodeNotFound", "GLSK node is not found in CGM")
.withTypedValue(NODE_ID_KEY, nodeId, "")
.withTypedValue(TYPE_KEY, type, "")
.withTypedValue(TSO_KEY, tso, "")
.withSeverity(WARN_SEVERITY)
.add();
}

public static void reportNoRunningGeneratorOrLoad(String nodeId, String type, String tso, ReportNode reportNode) {
reportNode.newReportNode()
.withMessageTemplate("entsoe.glsk.noRunningGeneratorOrLoad", "GLSK node is present but has no running Generator or Load")
.withTypedValue(NODE_ID_KEY, nodeId, "")
.withTypedValue(TYPE_KEY, type, "")
.withTypedValue(TSO_KEY, tso, "")
.withSeverity(WARN_SEVERITY)
.add();
}

public static void reportConnectedToAnIsland(String nodeId, String type, String tso, ReportNode reportNode) {
reportNode.newReportNode()
.withMessageTemplate("entsoe.glsk.connectedToAnIsland", "GLSK node is connected to an island")
.withTypedValue(NODE_ID_KEY, nodeId, "")
.withTypedValue(TYPE_KEY, type, "")
.withTypedValue(TSO_KEY, tso, "")
.withSeverity(WARN_SEVERITY)
.add();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import java.util.Map;
import java.util.stream.Collectors;

import static com.powsybl.commons.report.TypedValue.WARN_SEVERITY;
import static com.powsybl.glsk.commons.GlskReports.*;

/**
* @author Marc Erkol {@literal <marc.erkol at rte-france.com>}
Expand All @@ -30,12 +30,6 @@ class GlskQualityCheck {

private static final String LOAD = "A05";

public static final String NODE_ID_KEY = "NodeId";

public static final String TYPE_KEY = "Type";

public static final String TSO_KEY = "TSO";

public static void gskQualityCheck(GlskQualityCheckInput input, ReportNode reportNode) {
new GlskQualityCheck().generateReport(input, reportNode);
}
Expand Down Expand Up @@ -110,31 +104,15 @@ private void createMissingLoad(Network network, VoltageLevel voltageLevel, Strin

private void checkResource(GlskRegisteredResource registeredResource, Injection<?> injection, String type, Network network, String tso, ReportNode reportNode) {
if (injection == null) {

if (network.getBusBreakerView().getBus(registeredResource.getmRID()) == null) {
reportNode.newReportNode().withMessageTemplate("1", "GLSK node is not found in CGM")
.withTypedValue(NODE_ID_KEY, registeredResource.getmRID(), "")
.withTypedValue(TYPE_KEY, type, "")
.withTypedValue(TSO_KEY, tso, "")
.withSeverity(WARN_SEVERITY)
.add();
reportNodeNotFound(registeredResource.getmRID(), type, tso, reportNode);
} else {
reportNode.newReportNode().withMessageTemplate("2", "GLSK node is present but has no running Generator or Load")
.withTypedValue(NODE_ID_KEY, registeredResource.getmRID(), "")
.withTypedValue(TYPE_KEY, type, "")
.withTypedValue(TSO_KEY, tso, "")
.withSeverity(WARN_SEVERITY)
.add();
reportNoRunningGeneratorOrLoad(registeredResource.getmRID(), type, tso, reportNode);
}
} else {
if (!injection.getTerminal().isConnected()
|| !injection.getTerminal().getBusBreakerView().getBus().isInMainSynchronousComponent()) {
reportNode.newReportNode().withMessageTemplate("3", "GLSK node is connected to an island")
.withTypedValue(NODE_ID_KEY, registeredResource.getmRID(), "")
.withTypedValue(TYPE_KEY, type, "")
.withTypedValue(TSO_KEY, tso, "")
.withSeverity(WARN_SEVERITY)
.add();
reportConnectedToAnIsland(registeredResource.getmRID(), type, tso, reportNode);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import java.io.InputStream;
import java.time.Instant;

import static com.powsybl.glsk.commons.GlskReports.NODE_ID_KEY;
import static com.powsybl.glsk.commons.GlskReports.TSO_KEY;
import static org.junit.jupiter.api.Assertions.*;

/**
Expand Down Expand Up @@ -48,12 +50,12 @@ void qualityCheckWithError1() {
assertEquals(1, reporter.getChildren().size());
ReportNode r = reporter.getChildren().stream().findFirst().get();
assertEquals("GLSK node is not found in CGM", r.getMessage());
assertEquals("FFR2AA2 ", r.getValue(GlskQualityCheck.NODE_ID_KEY).get().toString());
assertEquals("10YFR-RTE------C", r.getValue(GlskQualityCheck.TSO_KEY).get().toString());
assertEquals("FFR2AA2 ", r.getValue(NODE_ID_KEY).get().toString());
assertEquals("10YFR-RTE------C", r.getValue(TSO_KEY).get().toString());
//Get unique TSO count in logs
assertEquals(1, reporter.getChildren().stream().filter(rep -> rep.getValue(GlskQualityCheck.TSO_KEY).get().toString().equals("10YFR-RTE------C")).count());
assertEquals(1, reporter.getChildren().stream().filter(rep -> rep.getValue(TSO_KEY).get().toString().equals("10YFR-RTE------C")).count());
//Get log count for RTE
assertEquals(1, reporter.getChildren().stream().map(rep -> rep.getValue(GlskQualityCheck.TSO_KEY).get().toString()).distinct().count());
assertEquals(1, reporter.getChildren().stream().map(rep -> rep.getValue(TSO_KEY).get().toString()).distinct().count());

}

Expand All @@ -67,8 +69,8 @@ void qualityCheckWithError2() {
assertEquals(1, reporter.getChildren().size());
ReportNode r = reporter.getChildren().stream().findFirst().get();
assertEquals("GLSK node is present but has no running Generator or Load", r.getMessage());
assertEquals("FFR2AA1 ", r.getValue(GlskQualityCheck.NODE_ID_KEY).get().toString());
assertEquals("10YFR-RTE------C", r.getValue(GlskQualityCheck.TSO_KEY).get().toString());
assertEquals("FFR2AA1 ", r.getValue(NODE_ID_KEY).get().toString());
assertEquals("10YFR-RTE------C", r.getValue(TSO_KEY).get().toString());
}

@Test
Expand All @@ -81,8 +83,8 @@ void qualityCheckWithError3() {
assertEquals(1, reporter.getChildren().size());
ReportNode r = reporter.getChildren().stream().findFirst().get();
assertEquals("GLSK node is connected to an island", r.getMessage());
assertEquals("FFR2AA1 ", r.getValue(GlskQualityCheck.NODE_ID_KEY).get().toString());
assertEquals("10YFR-RTE------C", r.getValue(GlskQualityCheck.TSO_KEY).get().toString());
assertEquals("FFR2AA1 ", r.getValue(NODE_ID_KEY).get().toString());
assertEquals("10YFR-RTE------C", r.getValue(TSO_KEY).get().toString());
}

@Test
Expand All @@ -95,8 +97,8 @@ void qualityCheckLoadNotConnected() {
assertEquals(1, reporter.getChildren().size());
ReportNode r = reporter.getChildren().stream().findFirst().get();
assertEquals("GLSK node is connected to an island", r.getMessage());
assertEquals("FFR2AA1 ", r.getValue(GlskQualityCheck.NODE_ID_KEY).get().toString());
assertEquals("10YFR-RTE------C", r.getValue(GlskQualityCheck.TSO_KEY).get().toString());
assertEquals("FFR2AA1 ", r.getValue(NODE_ID_KEY).get().toString());
assertEquals("10YFR-RTE------C", r.getValue(TSO_KEY).get().toString());
}

}