From 842445450f544dc12961fd9b4ba41c43ac92e90d Mon Sep 17 00:00:00 2001 From: lisrte Date: Thu, 19 Oct 2023 13:50:59 +0200 Subject: [PATCH 01/20] Use reporter instead of logger in DSL instantiation Signed-off-by: lisrte --- .../AbstractEquipmentGroovyExtension.groovy | 17 +- .../AbstractPureDynamicGroovyExtension.groovy | 13 +- ...tractSimpleEquipmentGroovyExtension.groovy | 17 +- .../powsybl/dynawaltz/dsl/DslEquipment.groovy | 8 +- .../dsl/DynaWaltzCurveGroovyExtension.groovy | 5 +- .../powsybl/dynawaltz/dsl/Reporters.groovy | 109 ++++++++++++ .../AbstractPhaseShifterModelBuilder.groovy | 7 +- ...urrentLimitAutomatonGroovyExtension.groovy | 21 ++- ...itTwoLevelsAutomatonGroovyExtension.groovy | 16 +- ...aseShifterIAutomatonGroovyExtension.groovy | 9 +- ...aseShifterPAutomatonGroovyExtension.groovy | 9 +- .../TapChangerAutomatonGroovyExtension.groovy | 11 +- ...gerBlockingAutomatonGroovyExtension.groovy | 20 ++- ...nderVoltageAutomatonGroovyExtension.groovy | 11 +- .../AbstractDynamicModelBuilder.groovy | 18 +- .../AbstractEquipmentModelBuilder.groovy | 16 +- .../builders/AbstractEventModelBuilder.groovy | 15 +- .../AbstractPureDynamicModelBuilder.groovy | 15 +- ...ActivePowerVariationGroovyExtension.groovy | 16 +- .../EventDisconnectionGroovyExtension.groovy | 19 ++- .../NodeFaultEventGroovyExtension.groovy | 16 +- .../models/buses/AbstractBusBuilder.groovy | 5 +- .../models/buses/BusGroovyExtension.groovy | 12 +- .../buses/InfiniteBusGroovyExtension.groovy | 12 +- .../AbstractGeneratorBuilder.groovy | 5 +- .../GeneratorFictitiousGroovyExtension.groovy | 12 +- ...GridFormingConverterGroovyExtension.groovy | 12 +- ...ynchronizedGeneratorGroovyExtension.groovy | 12 +- ...SynchronousGeneratorGroovyExtension.groovy | 12 +- .../generators/WeccGenGroovyExtension.groovy | 12 +- .../models/hvdc/AbstractHvdcBuilder.groovy | 10 +- .../models/hvdc/HvdcPGroovyExtension.groovy | 12 +- .../models/hvdc/HvdcVscGroovyExtension.groovy | 12 +- .../models/lines/LineGroovyExtension.groovy | 12 +- .../loads/AbstractLoadModelBuilder.groovy | 5 +- .../loads/BaseLoadGroovyExtension.groovy | 12 +- .../LoadOneTransformerGroovyExtension.groovy | 12 +- ...ransformerTapChangerGroovyExtension.groovy | 12 +- .../LoadTwoTransformersGroovyExtension.groovy | 12 +- ...nsformersTapChangersGroovyExtension.groovy | 12 +- .../models/svarcs/SvarcGroovyExtension.groovy | 12 +- ...ransformerFixedRatioGroovyExtension.groovy | 12 +- .../dsl/AbstractModelSupplierTest.java | 13 ++ .../dsl/DynamicModelsSupplierTest.java | 158 +++++++++++++++--- .../dsl/EventModelsSupplierTest.java | 61 ++++++- .../dynawaltz/dsl/ieee/AbstractIeeeTest.java | 5 +- .../eventWarnings/missingAPVParameters.groovy | 2 +- .../powsybl/dynawaltz/DynaWaltzProvider.java | 14 +- .../dynawaltz/DynaWaltzProviderTest.java | 24 +-- .../com/powsybl/dynawo/it/DynaWaltzTest.java | 9 +- .../src/test/resources/hvdc/models.par | 2 + pom.xml | 2 +- 52 files changed, 618 insertions(+), 289 deletions(-) create mode 100644 dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/Reporters.groovy diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractEquipmentGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractEquipmentGroovyExtension.groovy index 5aece47d8..5d67e68ea 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractEquipmentGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractEquipmentGroovyExtension.groovy @@ -7,14 +7,18 @@ */ package com.powsybl.dynawaltz.dsl +import com.powsybl.commons.reporter.Reporter +import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.DynaWaltzProvider import com.powsybl.iidm.network.Network import java.util.function.Consumer + /** * @author Laurent Issertial */ -abstract class AbstractEquipmentGroovyExtension { +abstract class AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { protected static final String MODELS_CONFIG = "models.json" @@ -28,21 +32,26 @@ abstract class AbstractEquipmentGroovyExtension { equipmentConfigs = ModelsSlurper.instance.getEquipmentConfigs(modelConfigUrl, modelTag) } - abstract protected ModelBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) + abstract protected ModelBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) + @Override String getName() { DynaWaltzProvider.NAME } + @Override List getModelNames() { equipmentConfigs.collect(eq -> eq.lib) } - void load(Binding binding, Consumer consumer) { + @Override + void load(Binding binding, Consumer consumer, Reporter reporter) { equipmentConfigs.forEach { binding.setVariable(it.lib, { Closure closure -> def cloned = closure.clone() - ModelBuilder builder = createBuilder(binding.getVariable("network") as Network, it) + ModelBuilder builder = createBuilder(binding.getVariable("network") as Network, + it, + Reporters.createModelBuilderReporter(reporter, it.lib)) cloned.delegate = builder cloned() builder.build()?.tap { diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractPureDynamicGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractPureDynamicGroovyExtension.groovy index f7731264d..bf4522706 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractPureDynamicGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractPureDynamicGroovyExtension.groovy @@ -7,6 +7,8 @@ */ package com.powsybl.dynawaltz.dsl +import com.powsybl.commons.reporter.Reporter +import com.powsybl.dynamicsimulation.groovy.GroovyExtension import com.powsybl.dynawaltz.DynaWaltzProvider import com.powsybl.iidm.network.Network @@ -15,12 +17,13 @@ import java.util.function.Consumer /** * @author Laurent Issertial */ -abstract class AbstractPureDynamicGroovyExtension { +abstract class AbstractPureDynamicGroovyExtension implements GroovyExtension { protected List modelTags - abstract protected ModelBuilder createBuilder(Network network) + abstract protected ModelBuilder createBuilder(Network network, Reporter reporter) + @Override String getName() { DynaWaltzProvider.NAME } @@ -29,11 +32,13 @@ abstract class AbstractPureDynamicGroovyExtension { modelTags } - void load(Binding binding, Consumer consumer) { + @Override + void load(Binding binding, Consumer consumer, Reporter reporter) { modelTags.forEach { binding.setVariable(it, { Closure closure -> def cloned = closure.clone() - ModelBuilder builder = createBuilder(binding.getVariable("network") as Network) + ModelBuilder builder = createBuilder(binding.getVariable("network") as Network, + Reporters.createModelBuilderReporter(reporter, it)) cloned.delegate = builder cloned() builder.build()?.tap { diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractSimpleEquipmentGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractSimpleEquipmentGroovyExtension.groovy index 3f6802b0d..62f1da517 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractSimpleEquipmentGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractSimpleEquipmentGroovyExtension.groovy @@ -7,6 +7,9 @@ */ package com.powsybl.dynawaltz.dsl +import com.powsybl.commons.reporter.Reporter +import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.DynaWaltzProvider import com.powsybl.iidm.network.Network @@ -15,7 +18,7 @@ import java.util.function.Consumer /** * @author Laurent Issertial */ -abstract class AbstractSimpleEquipmentGroovyExtension { +abstract class AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { protected EquipmentConfig equipmentConfig @@ -23,21 +26,25 @@ abstract class AbstractSimpleEquipmentGroovyExtension { equipmentConfig = new EquipmentConfig(modelTag) } + abstract protected ModelBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) - abstract protected ModelBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) - + @Override String getName() { DynaWaltzProvider.NAME } + @Override List getModelNames() { List.of(equipmentConfig.lib) } - void load(Binding binding, Consumer consumer) { + @Override + void load(Binding binding, Consumer consumer, Reporter reporter) { binding.setVariable(equipmentConfig.lib, { Closure closure -> def cloned = closure.clone() - ModelBuilder builder = createBuilder(binding.getVariable("network") as Network, equipmentConfig) + ModelBuilder builder = createBuilder(binding.getVariable("network") as Network, + equipmentConfig, + Reporters.createModelBuilderReporter(reporter, equipmentConfig.lib)) cloned.delegate = builder cloned() builder.build()?.tap { diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/DslEquipment.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/DslEquipment.groovy index 0b994f0da..864b8316a 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/DslEquipment.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/DslEquipment.groovy @@ -7,9 +7,9 @@ */ package com.powsybl.dynawaltz.dsl +import com.powsybl.commons.reporter.Reporter import com.powsybl.iidm.network.Identifiable import com.powsybl.iidm.network.IdentifiableType -import org.slf4j.Logger import java.util.function.Function @@ -48,12 +48,12 @@ class DslEquipment { equipment = equipmentSupplier(staticId) } - boolean checkEquipmentData(Logger logger, String lib) { + boolean checkEquipmentData(Reporter reporter) { if (!staticId) { - logger.warn("$lib: '$fieldName' field is not set") + Reporters.reportFieldNotSet(reporter, fieldName) return false } else if (!equipment) { - logger.warn("$lib: $equipmentType static id unknown : $staticId") + Reporters.reportStaticIdUnknown(reporter, fieldName, staticId, equipmentType) return false } true diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/DynaWaltzCurveGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/DynaWaltzCurveGroovyExtension.groovy index f2c0f0540..b13f8dd4d 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/DynaWaltzCurveGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/DynaWaltzCurveGroovyExtension.groovy @@ -7,6 +7,7 @@ package com.powsybl.dynawaltz.dsl import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dsl.DslException import com.powsybl.dynamicsimulation.Curve import com.powsybl.dynamicsimulation.groovy.CurveGroovyExtension @@ -51,6 +52,7 @@ class DynaWaltzCurveGroovyExtension implements CurveGroovyExtension { } } + @Override String getName() { DynaWaltzProvider.NAME } @@ -76,7 +78,8 @@ class DynaWaltzCurveGroovyExtension implements CurveGroovyExtension { } } - void load(Binding binding, Consumer consumer) { + @Override + void load(Binding binding, Consumer consumer, Reporter reporter) { binding.curve = { Closure closure -> def cloned = closure.clone() CurvesSpec curveSpec = new CurvesSpec() diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/Reporters.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/Reporters.groovy new file mode 100644 index 000000000..735d48608 --- /dev/null +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/Reporters.groovy @@ -0,0 +1,109 @@ +/** + * 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/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.dynawaltz.dsl + +import com.powsybl.commons.reporter.Report +import com.powsybl.commons.reporter.Reporter +import com.powsybl.commons.reporter.TypedValue +import com.powsybl.iidm.network.IdentifiableType + +/** + * @author Laurent Issertial + */ +final class Reporters { + + private Reporters() { + } + + static Reporter createModelBuilderReporter(Reporter reporter, String lib) { + reporter.createSubReporter("DSLModelBuilder", + 'DSL model builder for ${lib}', + "lib", lib) + } + + static void reportModelInstantiation(Reporter reporter) { + reporter.report(Report.builder() + .withKey("modelInstantiation") + .withDefaultMessage('Instantiation successful') + .withSeverity(TypedValue.TRACE_SEVERITY) + .build()) + } + + static void reportModelInstantiationFailure(Reporter reporter) { + reporter.report(Report.builder() + .withKey("modelInstantiation") + .withDefaultMessage('Model cannot be instantiated') + .withSeverity(TypedValue.WARN_SEVERITY) + .build()) + } + + static void reportFieldReplacement(Reporter reporter, String fieldName, String replacementName, String replacement) { + reporter.report(Report.builder() + .withKey("fieldReplacement") + .withDefaultMessage('\'${fieldName}\' field is not set, ${replacementName} ${replacement} will be used instead') + .withValue("fieldName", fieldName) + .withValue("replacementName", replacementName) + .withValue("replacement", replacement) + .withSeverity(TypedValue.TRACE_SEVERITY) + .build()) + } + + static void reportFieldNotSet(Reporter reporter, String fieldName) { + reporter.report(Report.builder() + .withKey("fieldNotSet") + .withDefaultMessage('\'${fieldName}\' field is not set') + .withValue("fieldName", fieldName) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()) + } + + static void reportStaticIdUnknown(Reporter reporter, String fieldName, String staticId, String equipmentType) { + reporter.report(Report.builder() + .withKey("fieldNotSet") + .withDefaultMessage('\'${fieldName}\' field value \'${staticId}\' not found for equipment type(s) ${equipmentType}') + .withValue("equipmentType", equipmentType) + .withValue("fieldName", fieldName) + .withValue("staticId", staticId) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()) + } + + static void reportCrossThreshold(Reporter reporter, String fieldName, double fieldValue, String threshold) { + reporter.report(Report.builder() + .withKey("crossThreshold") + .withDefaultMessage('${fieldName} should be ${threshold} (${fieldValue})') + .withValue("fieldName", fieldName) + .withValue("fieldValue", fieldValue) + .withValue("threshold", threshold) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()) + } + + static void reportEmptyList(Reporter reporter, String fieldName) { + reporter.report(Report.builder() + .withKey("emptyList") + .withDefaultMessage('\'${fieldName}\' list is empty') + .withValue("fieldName", fieldName) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()) + } + + static void reportFieldSetWithWrongEquipment(Reporter reporter, String fieldName, IdentifiableType equipmentType, String staticId) { + reportFieldSetWithWrongEquipment(reporter, fieldName, equipmentType.toString() + " " + staticId) + } + + static void reportFieldSetWithWrongEquipment(Reporter reporter, String fieldName, String equipment) { + reporter.report(Report.builder() + .withKey("fieldSetWithWrongEquipment") + .withDefaultMessage('\'${fieldName}\' field is set but ${equipment} does not possess this option') + .withValue("fieldName", fieldName) + .withValue("equipment", equipment) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()) + } +} diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/AbstractPhaseShifterModelBuilder.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/AbstractPhaseShifterModelBuilder.groovy index 3bb3f7a2a..1fd1f7b1a 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/AbstractPhaseShifterModelBuilder.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/AbstractPhaseShifterModelBuilder.groovy @@ -7,6 +7,7 @@ */ package com.powsybl.dynawaltz.dsl.automatons +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynawaltz.dsl.DslEquipment import com.powsybl.dynawaltz.dsl.builders.AbstractPureDynamicModelBuilder import com.powsybl.iidm.network.IdentifiableType @@ -20,8 +21,8 @@ abstract class AbstractPhaseShifterModelBuilder extends AbstractPureDynamicModel protected final DslEquipment dslTransformer - AbstractPhaseShifterModelBuilder(Network network, String lib) { - super(network, lib) + AbstractPhaseShifterModelBuilder(Network network, String lib, Reporter reporter) { + super(network, lib, reporter) dslTransformer = new DslEquipment<>(IdentifiableType.TWO_WINDINGS_TRANSFORMER, "transformer") } @@ -32,6 +33,6 @@ abstract class AbstractPhaseShifterModelBuilder extends AbstractPureDynamicModel @Override protected void checkData() { super.checkData() - isInstantiable &= dslTransformer.checkEquipmentData(LOGGER, getLib()) + isInstantiable &= dslTransformer.checkEquipmentData(reporter) } } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/CurrentLimitAutomatonGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/CurrentLimitAutomatonGroovyExtension.groovy index 376ab2a2b..a60136afd 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/CurrentLimitAutomatonGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/CurrentLimitAutomatonGroovyExtension.groovy @@ -8,15 +8,18 @@ package com.powsybl.dynawaltz.dsl.automatons import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractPureDynamicGroovyExtension import com.powsybl.dynawaltz.dsl.DslEquipment +import com.powsybl.dynawaltz.dsl.Reporters import com.powsybl.dynawaltz.dsl.builders.AbstractPureDynamicModelBuilder import com.powsybl.dynawaltz.models.Side import com.powsybl.dynawaltz.models.automatons.CurrentLimitAutomaton import com.powsybl.dynawaltz.models.utils.SideConverter import com.powsybl.iidm.network.Branch +import com.powsybl.iidm.network.IdentifiableType import com.powsybl.iidm.network.Network /** @@ -32,8 +35,8 @@ class CurrentLimitAutomatonGroovyExtension extends AbstractPureDynamicGroovyExte } @Override - protected CurrentLimitAutomatonBuilder createBuilder(Network network) { - new CurrentLimitAutomatonBuilder(network, getLib()) + protected CurrentLimitAutomatonBuilder createBuilder(Network network, Reporter reporter) { + new CurrentLimitAutomatonBuilder(network, getLib(), reporter) } protected String getLib() { @@ -46,10 +49,10 @@ class CurrentLimitAutomatonGroovyExtension extends AbstractPureDynamicGroovyExte protected Side iMeasurementSide protected final DslEquipment controlledEquipment - CurrentLimitAutomatonBuilder(Network network, String lib) { - super(network, lib) - iMeasurement = new DslEquipment<>("I measurement quadripole", "iMeasurement") - controlledEquipment = new DslEquipment<>("Controlled quadripole", "controlledQuadripole") + CurrentLimitAutomatonBuilder(Network network, String lib, Reporter reporter) { + super(network, lib, reporter) + iMeasurement = new DslEquipment<>("Quadripole", "iMeasurement") + controlledEquipment = new DslEquipment<>("Quadripole", "controlledQuadripole") } void iMeasurement(String staticId) { @@ -67,10 +70,10 @@ class CurrentLimitAutomatonGroovyExtension extends AbstractPureDynamicGroovyExte @Override void checkData() { super.checkData() - isInstantiable &= controlledEquipment.checkEquipmentData(LOGGER, getLib()) - isInstantiable &= iMeasurement.checkEquipmentData(LOGGER, getLib()) + isInstantiable &= controlledEquipment.checkEquipmentData(reporter) + isInstantiable &= iMeasurement.checkEquipmentData(reporter) if (!iMeasurementSide) { - LOGGER.warn("${getLib()}: 'iMeasurementSide' field is not set") + Reporters.reportFieldNotSet(reporter, "iMeasurementSide") isInstantiable = false } } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/CurrentLimitTwoLevelsAutomatonGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/CurrentLimitTwoLevelsAutomatonGroovyExtension.groovy index ae524f77c..26978d21c 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/CurrentLimitTwoLevelsAutomatonGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/CurrentLimitTwoLevelsAutomatonGroovyExtension.groovy @@ -8,11 +8,13 @@ package com.powsybl.dynawaltz.dsl.automatons import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dsl.DslException import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractPureDynamicGroovyExtension import com.powsybl.dynawaltz.dsl.DslEquipment +import com.powsybl.dynawaltz.dsl.Reporters import com.powsybl.dynawaltz.models.Side import com.powsybl.dynawaltz.models.automatons.CurrentLimitTwoLevelsAutomaton import com.powsybl.dynawaltz.models.utils.SideConverter @@ -34,8 +36,8 @@ class CurrentLimitTwoLevelsAutomatonGroovyExtension extends AbstractPureDynamicG } @Override - protected CurrentLimitAutomatonTwoLevelBuilder createBuilder(Network network) { - new CurrentLimitAutomatonTwoLevelBuilder(network, getLib()) + protected CurrentLimitAutomatonTwoLevelBuilder createBuilder(Network network, Reporter reporter) { + new CurrentLimitAutomatonTwoLevelBuilder(network, getLib(), reporter) } static class CurrentLimitAutomatonTwoLevelBuilder extends CurrentLimitAutomatonGroovyExtension.CurrentLimitAutomatonBuilder { @@ -43,9 +45,9 @@ class CurrentLimitTwoLevelsAutomatonGroovyExtension extends AbstractPureDynamicG protected final DslEquipment iMeasurement2 protected Side iMeasurement2Side - CurrentLimitAutomatonTwoLevelBuilder(Network network, String lib) { - super(network, lib) - iMeasurement2 = new DslEquipment<>("I measurement 2 quadripole", "iMeasurement2") + CurrentLimitAutomatonTwoLevelBuilder(Network network, String lib, Reporter reporter) { + super(network, lib, reporter) + iMeasurement2 = new DslEquipment<>("Quadripole", "iMeasurement2") } void iMeasurement1(String staticId) { @@ -67,9 +69,9 @@ class CurrentLimitTwoLevelsAutomatonGroovyExtension extends AbstractPureDynamicG @Override void checkData() { super.checkData() - isInstantiable &= iMeasurement2.checkEquipmentData(LOGGER, getLib()) + isInstantiable &= iMeasurement2.checkEquipmentData(reporter) if (!iMeasurement2Side) { - LOGGER.warn("${getLib()}: 'iMeasurement2Side' field is not set") + Reporters.reportFieldNotSet(reporter, "iMeasurement2Side") isInstantiable = false } } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/PhaseShifterIAutomatonGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/PhaseShifterIAutomatonGroovyExtension.groovy index 2fd7ecb80..b79764d1a 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/PhaseShifterIAutomatonGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/PhaseShifterIAutomatonGroovyExtension.groovy @@ -8,6 +8,7 @@ package com.powsybl.dynawaltz.dsl.automatons import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractPureDynamicGroovyExtension @@ -27,14 +28,14 @@ class PhaseShifterIAutomatonGroovyExtension extends AbstractPureDynamicGroovyExt } @Override - protected PhaseShifterPAutomatonBuilder createBuilder(Network network) { - new PhaseShifterPAutomatonBuilder(network, LIB) + protected PhaseShifterPAutomatonBuilder createBuilder(Network network, Reporter reporter) { + new PhaseShifterPAutomatonBuilder(network, LIB, reporter) } static class PhaseShifterPAutomatonBuilder extends AbstractPhaseShifterModelBuilder { - PhaseShifterPAutomatonBuilder(Network network, String lib) { - super(network, lib) + PhaseShifterPAutomatonBuilder(Network network, String lib, Reporter reporter) { + super(network, lib, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/PhaseShifterPAutomatonGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/PhaseShifterPAutomatonGroovyExtension.groovy index f2b6485f8..a91ac8229 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/PhaseShifterPAutomatonGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/PhaseShifterPAutomatonGroovyExtension.groovy @@ -8,6 +8,7 @@ package com.powsybl.dynawaltz.dsl.automatons import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractPureDynamicGroovyExtension @@ -27,14 +28,14 @@ class PhaseShifterPAutomatonGroovyExtension extends AbstractPureDynamicGroovyExt } @Override - protected PhaseShifterPAutomatonBuilder createBuilder(Network network) { - new PhaseShifterPAutomatonBuilder(network, LIB) + protected PhaseShifterPAutomatonBuilder createBuilder(Network network, Reporter reporter) { + new PhaseShifterPAutomatonBuilder(network, LIB, reporter) } static class PhaseShifterPAutomatonBuilder extends AbstractPhaseShifterModelBuilder { - PhaseShifterPAutomatonBuilder(Network network, String lib) { - super(network, lib) + PhaseShifterPAutomatonBuilder(Network network, String lib, Reporter reporter) { + super(network, lib, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/TapChangerAutomatonGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/TapChangerAutomatonGroovyExtension.groovy index ded9402c3..7b3bf1d75 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/TapChangerAutomatonGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/TapChangerAutomatonGroovyExtension.groovy @@ -8,6 +8,7 @@ package com.powsybl.dynawaltz.dsl.automatons import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractPureDynamicGroovyExtension @@ -30,8 +31,8 @@ class TapChangerAutomatonGroovyExtension extends AbstractPureDynamicGroovyExtens } @Override - protected TapChangerAutomatonBuilder createBuilder(Network network) { - new TapChangerAutomatonBuilder(network, LIB) + protected TapChangerAutomatonBuilder createBuilder(Network network, Reporter reporter) { + new TapChangerAutomatonBuilder(network, LIB, reporter) } static class TapChangerAutomatonBuilder extends AbstractPureDynamicModelBuilder { @@ -39,8 +40,8 @@ class TapChangerAutomatonGroovyExtension extends AbstractPureDynamicGroovyExtens protected final DslEquipment dslLoad protected TransformerSide side = TransformerSide.NONE - TapChangerAutomatonBuilder(Network network, String lib) { - super(network, lib) + TapChangerAutomatonBuilder(Network network, String lib, Reporter reporter) { + super(network, lib, reporter) dslLoad = new DslEquipment<>(IdentifiableType.LOAD) } @@ -55,7 +56,7 @@ class TapChangerAutomatonGroovyExtension extends AbstractPureDynamicGroovyExtens @Override protected void checkData() { super.checkData() - isInstantiable &= dslLoad.checkEquipmentData(LOGGER, getLib()) + isInstantiable &= dslLoad.checkEquipmentData(reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/TapChangerBlockingAutomatonGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/TapChangerBlockingAutomatonGroovyExtension.groovy index 396c4cbfe..e978a27cb 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/TapChangerBlockingAutomatonGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/TapChangerBlockingAutomatonGroovyExtension.groovy @@ -8,9 +8,11 @@ package com.powsybl.dynawaltz.dsl.automatons import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractPureDynamicGroovyExtension +import com.powsybl.dynawaltz.dsl.Reporters import com.powsybl.dynawaltz.dsl.builders.AbstractPureDynamicModelBuilder import com.powsybl.dynawaltz.models.automatons.TapChangerBlockingAutomaton import com.powsybl.iidm.network.Bus @@ -33,8 +35,8 @@ class TapChangerBlockingAutomatonGroovyExtension extends AbstractPureDynamicGroo } @Override - protected TCBAutomatonBuilder createBuilder(Network network) { - new TCBAutomatonBuilder(network, LIB) + protected TCBAutomatonBuilder createBuilder(Network network, Reporter reporter) { + new TCBAutomatonBuilder(network, LIB, reporter) } static class TCBAutomatonBuilder extends AbstractPureDynamicModelBuilder { @@ -44,8 +46,8 @@ class TapChangerBlockingAutomatonGroovyExtension extends AbstractPureDynamicGroo List uMeasurements = [] List tapChangerAutomatonIds = [] - TCBAutomatonBuilder(Network network, String lib) { - super(network, lib) + TCBAutomatonBuilder(Network network, String lib, Reporter reporter) { + super(network, lib, reporter) } void transformers(String[] staticIds) { @@ -69,7 +71,7 @@ class TapChangerBlockingAutomatonGroovyExtension extends AbstractPureDynamicGroo Identifiable checkEquipment(String staticId) { network.getIdentifiable(staticId)?.tap { if (!TapChangerBlockingAutomaton.isCompatibleEquipment(type)) { - LOGGER.warn("${getLib()}: $type $staticId is not compatible") + Reporters.reportStaticIdUnknown(reporter, "uMeasurements", staticId, "LOAD/TWO_WINDINGS_TRANSFORMER") } } } @@ -78,7 +80,7 @@ class TapChangerBlockingAutomatonGroovyExtension extends AbstractPureDynamicGroo uMeasurements = staticIds.collect { def bus = network.busBreakerView.getBus(it) if (!bus) { - LOGGER.warn("${getLib()}: $IdentifiableType.BUS static id unknown : $it") + Reporters.reportStaticIdUnknown(reporter, "uMeasurements", it, IdentifiableType.BUS.toString()) } bus } @@ -87,17 +89,17 @@ class TapChangerBlockingAutomatonGroovyExtension extends AbstractPureDynamicGroo @Override protected void checkData() { if (!uMeasurements) { - LOGGER.warn("${getLib()}: 'uMeasurements' field is not set") + Reporters.reportFieldNotSet(reporter, "uMeasurements") isInstantiable = false } else { uMeasurements -= null if (!uMeasurements) { - LOGGER.warn("${getLib()}: 'uMeasurements' is empty") + Reporters.reportEmptyList(reporter, "uMeasurements") isInstantiable = false } } if(!loads && !transformers && !tapChangerAutomatonIds) { - LOGGER.warn("${getLib()}: 'transformers' field is empty") + Reporters.reportEmptyList(reporter, "transformers") isInstantiable = false } } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/UnderVoltageAutomatonGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/UnderVoltageAutomatonGroovyExtension.groovy index 0ffedf963..f4c33e584 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/UnderVoltageAutomatonGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/automatons/UnderVoltageAutomatonGroovyExtension.groovy @@ -8,6 +8,7 @@ package com.powsybl.dynawaltz.dsl.automatons import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractPureDynamicGroovyExtension @@ -31,16 +32,16 @@ class UnderVoltageAutomatonGroovyExtension extends AbstractPureDynamicGroovyExte } @Override - protected UnderVoltageAutomatonBuilder createBuilder(Network network) { - new UnderVoltageAutomatonBuilder(network, LIB) + protected UnderVoltageAutomatonBuilder createBuilder(Network network, Reporter reporter) { + new UnderVoltageAutomatonBuilder(network, LIB, reporter) } static class UnderVoltageAutomatonBuilder extends AbstractPureDynamicModelBuilder { protected final DslEquipment dslGenerator - UnderVoltageAutomatonBuilder(Network network, String lib) { - super(network, lib) + UnderVoltageAutomatonBuilder(Network network, String lib, Reporter reporter) { + super(network, lib, reporter) dslGenerator = new DslEquipment<>(IdentifiableType.GENERATOR, "generator") } @@ -51,7 +52,7 @@ class UnderVoltageAutomatonGroovyExtension extends AbstractPureDynamicGroovyExte @Override protected void checkData() { super.checkData() - isInstantiable &= dslGenerator.checkEquipmentData(LOGGER, getLib()) + isInstantiable &= dslGenerator.checkEquipmentData(reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractDynamicModelBuilder.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractDynamicModelBuilder.groovy index 8692413f2..e2fd61283 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractDynamicModelBuilder.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractDynamicModelBuilder.groovy @@ -7,32 +7,34 @@ */ package com.powsybl.dynawaltz.dsl.builders +import com.powsybl.commons.reporter.Reporter +import com.powsybl.dynawaltz.dsl.Reporters import com.powsybl.iidm.network.Network -import org.slf4j.Logger -import org.slf4j.LoggerFactory /** * @author Laurent Issertial */ abstract class AbstractDynamicModelBuilder { - protected static final Logger LOGGER = LoggerFactory.getLogger("DynamicModelBuilder") - protected final Network network + protected final Reporter reporter protected boolean isInstantiable = true + protected AbstractDynamicModelBuilder(Network network, Reporter reporter) { + this.network = network + this.reporter = reporter + } + protected AbstractDynamicModelBuilder(Network network) { this.network = network + this.reporter = null } abstract protected void checkData() protected final boolean isInstantiable() { checkData() - isInstantiable ? LOGGER.debug("${getLib()} instanciation successful") - : LOGGER.warn("${getLib()} cannot be instantiated") + isInstantiable ? Reporters.reportModelInstantiation(reporter) : Reporters.reportModelInstantiationFailure(reporter) isInstantiable } - - abstract protected String getLib() } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEquipmentModelBuilder.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEquipmentModelBuilder.groovy index 52bb16bcd..d6681018b 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEquipmentModelBuilder.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEquipmentModelBuilder.groovy @@ -7,10 +7,12 @@ */ package com.powsybl.dynawaltz.dsl.builders +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynawaltz.dsl.DslEquipment import com.powsybl.dynawaltz.dsl.EquipmentConfig import com.powsybl.dynawaltz.dsl.ModelBuilder +import com.powsybl.dynawaltz.dsl.Reporters import com.powsybl.iidm.network.Identifiable import com.powsybl.iidm.network.IdentifiableType import com.powsybl.iidm.network.Network @@ -25,8 +27,8 @@ abstract class AbstractEquipmentModelBuilder extends Abs protected final EquipmentConfig equipmentConfig protected final DslEquipment dslEquipment - protected AbstractEquipmentModelBuilder(Network network, EquipmentConfig equipmentConfig, IdentifiableType equipmentType) { - super(network) + protected AbstractEquipmentModelBuilder(Network network, EquipmentConfig equipmentConfig, IdentifiableType equipmentType, Reporter reporter) { + super(network, reporter) this.equipmentConfig = equipmentConfig this.dslEquipment = new DslEquipment(equipmentType) } @@ -45,12 +47,13 @@ abstract class AbstractEquipmentModelBuilder extends Abs @Override protected void checkData() { - isInstantiable = dslEquipment.checkEquipmentData(LOGGER, getLib()) + isInstantiable = dslEquipment.checkEquipmentData(reporter) if (!parameterSetId) { - LOGGER.warn("${getLib()}: 'parameterSetId' field is not set") + Reporters.reportFieldNotSet(reporter, "parameterSetId") isInstantiable = false } if (!dynamicModelId) { + Reporters.reportFieldReplacement(reporter, "dynamicModelId", "staticId", dslEquipment.staticId ?: "(unknown staticId)") dynamicModelId = dslEquipment.staticId } } @@ -61,11 +64,6 @@ abstract class AbstractEquipmentModelBuilder extends Abs dslEquipment.equipment } - @Override - String getLib() { - equipmentConfig.getLib() - } - @Override abstract DynamicModel build() } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEventModelBuilder.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEventModelBuilder.groovy index 623ffe75c..455f14a6f 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEventModelBuilder.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEventModelBuilder.groovy @@ -8,9 +8,11 @@ package com.powsybl.dynawaltz.dsl.builders +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.EventModel import com.powsybl.dynawaltz.dsl.DslEquipment import com.powsybl.dynawaltz.dsl.ModelBuilder +import com.powsybl.dynawaltz.dsl.Reporters import com.powsybl.iidm.network.Identifiable import com.powsybl.iidm.network.Network @@ -24,8 +26,8 @@ abstract class AbstractEventModelBuilder extends Abstrac protected String staticId protected double startTime - AbstractEventModelBuilder(Network network, DslEquipment dslEquipment, String tag) { - super(network) + AbstractEventModelBuilder(Network network, DslEquipment dslEquipment, String tag, Reporter reporter) { + super(network, reporter) this.dslEquipment = dslEquipment this.tag = tag } @@ -40,20 +42,15 @@ abstract class AbstractEventModelBuilder extends Abstrac @Override protected void checkData() { - isInstantiable &= dslEquipment.checkEquipmentData(LOGGER, getLib()) + isInstantiable &= dslEquipment.checkEquipmentData(reporter) if (!startTime) { - LOGGER.warn("${getLib()}: 'startTime' field is not set") + Reporters.reportFieldNotSet(reporter, "startTime") isInstantiable = false } } abstract protected Identifiable findEquipment(String staticId) - @Override - protected String getLib() { - tag - } - @Override abstract EventModel build() } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractPureDynamicModelBuilder.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractPureDynamicModelBuilder.groovy index f4f8418c5..1bd2f2388 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractPureDynamicModelBuilder.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractPureDynamicModelBuilder.groovy @@ -7,8 +7,10 @@ */ package com.powsybl.dynawaltz.dsl.builders +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynawaltz.dsl.ModelBuilder +import com.powsybl.dynawaltz.dsl.Reporters import com.powsybl.iidm.network.Network /** @@ -20,8 +22,8 @@ abstract class AbstractPureDynamicModelBuilder extends AbstractDynamicModelBuild protected String parameterSetId protected final String lib - AbstractPureDynamicModelBuilder(Network network, String lib) { - super(network) + AbstractPureDynamicModelBuilder(Network network, String lib, Reporter reporter) { + super(network, reporter) this.lib = lib } @@ -36,20 +38,15 @@ abstract class AbstractPureDynamicModelBuilder extends AbstractDynamicModelBuild @Override protected void checkData() { if (!dynamicModelId) { - LOGGER.warn("${getLib()}: 'dynamicModelId' field is not set") + Reporters.reportFieldNotSet(reporter, "dynamicModelId") isInstantiable = false } if (!parameterSetId) { - LOGGER.warn("${getLib()}: 'parameterSetId' field is not set") + Reporters.reportFieldNotSet(reporter, "dynamicModelId") isInstantiable = false } } - @Override - protected String getLib() { - lib - } - @Override abstract DynamicModel build() } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/EventActivePowerVariationGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/EventActivePowerVariationGroovyExtension.groovy index 47ddbbca6..bcb7ee77f 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/EventActivePowerVariationGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/EventActivePowerVariationGroovyExtension.groovy @@ -8,10 +8,12 @@ package com.powsybl.dynawaltz.dsl.events import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.EventModel import com.powsybl.dynamicsimulation.groovy.EventModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractPureDynamicGroovyExtension import com.powsybl.dynawaltz.dsl.DslFilteredEquipment +import com.powsybl.dynawaltz.dsl.Reporters import com.powsybl.dynawaltz.dsl.builders.AbstractEventModelBuilder import com.powsybl.dynawaltz.models.events.EventActivePowerVariation import com.powsybl.iidm.network.Identifiable @@ -31,16 +33,16 @@ class EventActivePowerVariationGroovyExtension extends AbstractPureDynamicGroovy } @Override - protected EventAPVBuilder createBuilder(Network network) { - new EventAPVBuilder(network, TAG) + protected EventAPVBuilder createBuilder(Network network, Reporter reporter) { + new EventAPVBuilder(network, TAG, reporter) } static class EventAPVBuilder extends AbstractEventModelBuilder { protected double deltaP - EventAPVBuilder(Network network, String tag) { - super(network, new DslFilteredEquipment("Generator/Load", EventActivePowerVariation::isConnectable), tag) + EventAPVBuilder(Network network, String tag, Reporter reporter) { + super(network, new DslFilteredEquipment("GENERATOR/LOAD", EventActivePowerVariation::isConnectable), tag, reporter) } void deltaP(double deltaP) { @@ -49,12 +51,8 @@ class EventActivePowerVariationGroovyExtension extends AbstractPureDynamicGroovy void checkData() { super.checkData() - if (dslEquipment.equipment && !EventActivePowerVariation.isConnectable(dslEquipment.equipment.type)) { - LOGGER.warn("${getLib()}: ${dslEquipment.equipment?.type} ${dslEquipment.staticId} cannot be disconnected") - isInstantiable = false - } if (!deltaP) { - LOGGER.warn("${getLib()}: 'deltaP' field is not set") + Reporters.reportFieldNotSet(reporter, "deltaP") isInstantiable = false } } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/EventDisconnectionGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/EventDisconnectionGroovyExtension.groovy index 3cb073635..f1d7b5215 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/EventDisconnectionGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/EventDisconnectionGroovyExtension.groovy @@ -8,10 +8,12 @@ package com.powsybl.dynawaltz.dsl.events import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.EventModel import com.powsybl.dynamicsimulation.groovy.EventModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractPureDynamicGroovyExtension import com.powsybl.dynawaltz.dsl.DslEquipment +import com.powsybl.dynawaltz.dsl.Reporters import com.powsybl.dynawaltz.dsl.builders.AbstractEventModelBuilder import com.powsybl.dynawaltz.models.events.AbstractEvent import com.powsybl.dynawaltz.models.events.EventHvdcDisconnection @@ -40,8 +42,8 @@ class EventDisconnectionGroovyExtension extends AbstractPureDynamicGroovyExtensi } @Override - protected EventQuadripoleDisconnectionBuilder createBuilder(Network network) { - new EventQuadripoleDisconnectionBuilder(network, TAG) + protected EventQuadripoleDisconnectionBuilder createBuilder(Network network, Reporter reporter) { + new EventQuadripoleDisconnectionBuilder(network, TAG, reporter) } static class EventQuadripoleDisconnectionBuilder extends AbstractEventModelBuilder { @@ -54,8 +56,8 @@ class EventDisconnectionGroovyExtension extends AbstractPureDynamicGroovyExtensi private enum DisconnectionType {INJECTION, QUADRIPOLE, HVDC, NONE} - EventQuadripoleDisconnectionBuilder(Network network, String tag) { - super(network, new DslEquipment("Disconnectable equipment"), tag) + EventQuadripoleDisconnectionBuilder(Network network, String tag, Reporter reporter) { + super(network, new DslEquipment("Disconnectable equipment"), tag, reporter) } void disconnectOnly(Branch.Side side) { @@ -74,20 +76,20 @@ class EventDisconnectionGroovyExtension extends AbstractPureDynamicGroovyExtensi void checkData() { super.checkData() - disconnectionType(dslEquipment?.equipment?.type) + setDisconnectionType(dslEquipment?.equipment?.type) if(dslEquipment.equipment) { if (disconnectionType == DisconnectionType.NONE) { - LOGGER.warn("${getLib()}: ${dslEquipment.equipment?.type} ${dslEquipment.staticId} cannot be disconnected") + Reporters.reportStaticIdUnknown(reporter, "staticId", dslEquipment.staticId, "Disconnectable equipment") isInstantiable = false } if (DisconnectionType.INJECTION == disconnectionType && disconnectSide) { - LOGGER.warn("'${getLib()}: disconnectSide' has been set but ${dslEquipment.equipment?.type} ${dslEquipment.staticId} is not a quadripole with a disconnectable side") + Reporters.reportFieldSetWithWrongEquipment(reporter, "disconnectSide", dslEquipment.equipment?.type, dslEquipment.staticId) isInstantiable = false } } } - boolean disconnectionType(IdentifiableType type) { + void setDisconnectionType(IdentifiableType type) { if (type) { if (CONNECTABLE_INJECTIONS.contains(type)) { disconnectionType = DisconnectionType.INJECTION @@ -97,7 +99,6 @@ class EventDisconnectionGroovyExtension extends AbstractPureDynamicGroovyExtensi disconnectionType = DisconnectionType.HVDC } } - disconnectionType != DisconnectionType.NONE } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/NodeFaultEventGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/NodeFaultEventGroovyExtension.groovy index c103d955b..b1a67fe85 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/NodeFaultEventGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/NodeFaultEventGroovyExtension.groovy @@ -8,10 +8,12 @@ package com.powsybl.dynawaltz.dsl.events import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.EventModel import com.powsybl.dynamicsimulation.groovy.EventModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractPureDynamicGroovyExtension import com.powsybl.dynawaltz.dsl.DslEquipment +import com.powsybl.dynawaltz.dsl.Reporters import com.powsybl.dynawaltz.dsl.builders.AbstractEventModelBuilder import com.powsybl.dynawaltz.models.events.NodeFaultEvent import com.powsybl.iidm.network.Bus @@ -31,8 +33,8 @@ class NodeFaultEventGroovyExtension extends AbstractPureDynamicGroovyExtension { @@ -41,8 +43,8 @@ class NodeFaultEventGroovyExtension extends AbstractPureDynamicGroovyExtension(IdentifiableType.BUS), tag) + NodeFaultEventBuilder(Network network,String tag, Reporter reporter) { + super(network, new DslEquipment(IdentifiableType.BUS), tag, reporter) } void faultTime(double faultTime) { @@ -65,15 +67,15 @@ class NodeFaultEventGroovyExtension extends AbstractPureDynamicGroovyExtension { - AbstractBusBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig, IdentifiableType.BUS) + AbstractBusBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, IdentifiableType.BUS, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/BusGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/BusGroovyExtension.groovy index fb51f2d0a..531047f16 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/BusGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/BusGroovyExtension.groovy @@ -8,7 +8,7 @@ package com.powsybl.dynawaltz.dsl.models.buses import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractSimpleEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -21,21 +21,21 @@ import com.powsybl.iidm.network.Network * @author Dimitri Baudrier */ @AutoService(DynamicModelGroovyExtension.class) -class BusGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class BusGroovyExtension extends AbstractSimpleEquipmentGroovyExtension { BusGroovyExtension() { super("Bus") } @Override - protected BusBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { - new BusBuilder(network, equipmentConfig) + protected BusBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + new BusBuilder(network, equipmentConfig, reporter) } static class BusBuilder extends AbstractBusBuilder { - BusBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig) + BusBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/InfiniteBusGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/InfiniteBusGroovyExtension.groovy index 4dcb009d5..59fe319a2 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/InfiniteBusGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/InfiniteBusGroovyExtension.groovy @@ -8,7 +8,7 @@ package com.powsybl.dynawaltz.dsl.models.buses import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -19,7 +19,7 @@ import com.powsybl.iidm.network.Network * @author Laurent Issertial */ @AutoService(DynamicModelGroovyExtension.class) -class InfiniteBusGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class InfiniteBusGroovyExtension extends AbstractEquipmentGroovyExtension { protected static final String BUSES = "infiniteBuses" @@ -28,14 +28,14 @@ class InfiniteBusGroovyExtension extends AbstractEquipmentGroovyExtension { - AbstractGeneratorBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig, IdentifiableType.GENERATOR) + AbstractGeneratorBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, IdentifiableType.GENERATOR, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GeneratorFictitiousGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GeneratorFictitiousGroovyExtension.groovy index 5763ecc15..00aef38ae 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GeneratorFictitiousGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GeneratorFictitiousGroovyExtension.groovy @@ -7,7 +7,7 @@ package com.powsybl.dynawaltz.dsl.models.generators import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractSimpleEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -18,21 +18,21 @@ import com.powsybl.iidm.network.Network * @author Dimitri Baudrier */ @AutoService(DynamicModelGroovyExtension.class) -class GeneratorFictitiousGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class GeneratorFictitiousGroovyExtension extends AbstractSimpleEquipmentGroovyExtension { GeneratorFictitiousGroovyExtension() { super("GeneratorFictitious") } @Override - protected GeneratorFictitiousBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { - new GeneratorFictitiousBuilder(network, equipmentConfig) + protected GeneratorFictitiousBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + new GeneratorFictitiousBuilder(network, equipmentConfig, reporter) } static class GeneratorFictitiousBuilder extends AbstractGeneratorBuilder { - GeneratorFictitiousBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig) + GeneratorFictitiousBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GridFormingConverterGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GridFormingConverterGroovyExtension.groovy index de6a66c3d..74f7d47bb 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GridFormingConverterGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GridFormingConverterGroovyExtension.groovy @@ -8,7 +8,7 @@ package com.powsybl.dynawaltz.dsl.models.generators import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -19,7 +19,7 @@ import com.powsybl.iidm.network.Network * @author Laurent Issertial */ @AutoService(DynamicModelGroovyExtension.class) -class GridFormingConverterGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class GridFormingConverterGroovyExtension extends AbstractEquipmentGroovyExtension { private static final String GRID_FORMING_CONVERTER = "gridFormingConverter" @@ -28,14 +28,14 @@ class GridFormingConverterGroovyExtension extends AbstractEquipmentGroovyExtensi } @Override - protected GridFormingConverterBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { - new GridFormingConverterBuilder(network, equipmentConfig) + protected GridFormingConverterBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + new GridFormingConverterBuilder(network, equipmentConfig, reporter) } static class GridFormingConverterBuilder extends AbstractGeneratorBuilder { - GridFormingConverterBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig) + GridFormingConverterBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/SynchronizedGeneratorGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/SynchronizedGeneratorGroovyExtension.groovy index d8bc388c7..804607767 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/SynchronizedGeneratorGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/SynchronizedGeneratorGroovyExtension.groovy @@ -8,7 +8,7 @@ package com.powsybl.dynawaltz.dsl.models.generators import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -21,7 +21,7 @@ import com.powsybl.iidm.network.Network * @author Dimitri Baudrier */ @AutoService(DynamicModelGroovyExtension.class) -class SynchronizedGeneratorGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class SynchronizedGeneratorGroovyExtension extends AbstractEquipmentGroovyExtension { private static final String SYNCHRONIZED_GENERATORS = "synchronizedGenerators" @@ -34,14 +34,14 @@ class SynchronizedGeneratorGroovyExtension extends AbstractEquipmentGroovyExtens } @Override - protected SynchronizedGeneratorBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { - new SynchronizedGeneratorBuilder(network, equipmentConfig) + protected SynchronizedGeneratorBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + new SynchronizedGeneratorBuilder(network, equipmentConfig, reporter) } static class SynchronizedGeneratorBuilder extends AbstractGeneratorBuilder { - SynchronizedGeneratorBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig) + SynchronizedGeneratorBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/SynchronousGeneratorGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/SynchronousGeneratorGroovyExtension.groovy index 58e396623..4c02f177d 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/SynchronousGeneratorGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/SynchronousGeneratorGroovyExtension.groovy @@ -7,8 +7,8 @@ package com.powsybl.dynawaltz.dsl.models.generators import com.google.auto.service.AutoService +import com.powsybl.commons.reporter.Reporter import com.powsybl.dsl.DslException -import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -21,7 +21,7 @@ import com.powsybl.iidm.network.Network * @author Marcos de Miguel */ @AutoService(DynamicModelGroovyExtension.class) -class SynchronousGeneratorGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class SynchronousGeneratorGroovyExtension extends AbstractEquipmentGroovyExtension { protected static final String SYNCHRONOUS_GENERATORS = "synchronousGenerators" @@ -34,14 +34,14 @@ class SynchronousGeneratorGroovyExtension extends AbstractEquipmentGroovyExtensi } @Override - protected SynchronousGeneratorBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { - new SynchronousGeneratorBuilder(network, equipmentConfig) + protected SynchronousGeneratorBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + new SynchronousGeneratorBuilder(network, equipmentConfig, reporter) } static class SynchronousGeneratorBuilder extends AbstractGeneratorBuilder { - SynchronousGeneratorBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig) + SynchronousGeneratorBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, reporter) } protected EnumGeneratorComponent getGeneratorComponent() { diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/WeccGenGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/WeccGenGroovyExtension.groovy index 6a3a835ef..655f04504 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/WeccGenGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/WeccGenGroovyExtension.groovy @@ -8,7 +8,7 @@ package com.powsybl.dynawaltz.dsl.models.generators import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -20,7 +20,7 @@ import com.powsybl.iidm.network.Network * @author Laurent Issertial */ @AutoService(DynamicModelGroovyExtension.class) -class WeccGenGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class WeccGenGroovyExtension extends AbstractEquipmentGroovyExtension { private static final String WECC = "wecc" @@ -29,14 +29,14 @@ class WeccGenGroovyExtension extends AbstractEquipmentGroovyExtension */ @AutoService(DynamicModelGroovyExtension.class) -class HvdcPGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class HvdcPGroovyExtension extends AbstractEquipmentGroovyExtension { protected static final String HVDC_P = "hvdcP" @@ -33,14 +33,14 @@ class HvdcPGroovyExtension extends AbstractEquipmentGroovyExtension */ @AutoService(DynamicModelGroovyExtension.class) -class HvdcVscGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class HvdcVscGroovyExtension extends AbstractEquipmentGroovyExtension { protected static final String HVDC_VSC = "hvdcVsc" @@ -29,14 +29,14 @@ class HvdcVscGroovyExtension extends AbstractEquipmentGroovyExtension */ @AutoService(DynamicModelGroovyExtension.class) -class LineGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class LineGroovyExtension extends AbstractSimpleEquipmentGroovyExtension { LineGroovyExtension() { super("Line") } @Override - protected LineBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { - new LineBuilder(network, equipmentConfig) + protected LineBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + new LineBuilder(network, equipmentConfig, reporter) } static class LineBuilder extends AbstractEquipmentModelBuilder { - LineBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig, IdentifiableType.LINE) + LineBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, IdentifiableType.LINE, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/AbstractLoadModelBuilder.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/AbstractLoadModelBuilder.groovy index f757684d4..d0389d0a8 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/AbstractLoadModelBuilder.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/AbstractLoadModelBuilder.groovy @@ -7,6 +7,7 @@ */ package com.powsybl.dynawaltz.dsl.models.loads +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynawaltz.dsl.EquipmentConfig import com.powsybl.dynawaltz.dsl.builders.AbstractEquipmentModelBuilder import com.powsybl.iidm.network.IdentifiableType @@ -18,8 +19,8 @@ import com.powsybl.iidm.network.Network */ abstract class AbstractLoadModelBuilder extends AbstractEquipmentModelBuilder { - AbstractLoadModelBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig, IdentifiableType.LOAD) + AbstractLoadModelBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, IdentifiableType.LOAD, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/BaseLoadGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/BaseLoadGroovyExtension.groovy index af3e30e9f..8a2ee3dd3 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/BaseLoadGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/BaseLoadGroovyExtension.groovy @@ -7,7 +7,7 @@ package com.powsybl.dynawaltz.dsl.models.loads import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -21,7 +21,7 @@ import com.powsybl.iidm.network.Network * @author Marcos de Miguel */ @AutoService(DynamicModelGroovyExtension.class) -class BaseLoadGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class BaseLoadGroovyExtension extends AbstractEquipmentGroovyExtension { private static final String LOADS = "baseLoads" @@ -30,14 +30,14 @@ class BaseLoadGroovyExtension extends AbstractEquipmentGroovyExtension */ @AutoService(DynamicModelGroovyExtension.class) -class LoadOneTransformerGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class LoadOneTransformerGroovyExtension extends AbstractSimpleEquipmentGroovyExtension { LoadOneTransformerGroovyExtension() { super("LoadOneTransformer") } @Override - protected LoadOneTransformerBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { - new LoadOneTransformerBuilder(network, equipmentConfig) + protected LoadOneTransformerBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + new LoadOneTransformerBuilder(network, equipmentConfig, reporter) } static class LoadOneTransformerBuilder extends AbstractLoadModelBuilder { - LoadOneTransformerBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig) + LoadOneTransformerBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadOneTransformerTapChangerGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadOneTransformerTapChangerGroovyExtension.groovy index f7661b348..21bbc7b46 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadOneTransformerTapChangerGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadOneTransformerTapChangerGroovyExtension.groovy @@ -8,7 +8,7 @@ package com.powsybl.dynawaltz.dsl.models.loads import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractSimpleEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -19,21 +19,21 @@ import com.powsybl.iidm.network.Network * @author Laurent Issertial */ @AutoService(DynamicModelGroovyExtension.class) -class LoadOneTransformerTapChangerGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class LoadOneTransformerTapChangerGroovyExtension extends AbstractSimpleEquipmentGroovyExtension { LoadOneTransformerTapChangerGroovyExtension() { super("LoadOneTransformerTapChanger") } @Override - protected LoadOneTransformerTapChangerBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { - new LoadOneTransformerTapChangerBuilder(network, equipmentConfig) + protected LoadOneTransformerTapChangerBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + new LoadOneTransformerTapChangerBuilder(network, equipmentConfig, reporter) } static class LoadOneTransformerTapChangerBuilder extends AbstractLoadModelBuilder { - LoadOneTransformerTapChangerBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig) + LoadOneTransformerTapChangerBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersGroovyExtension.groovy index 37324d45c..d2b071a54 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersGroovyExtension.groovy @@ -8,7 +8,7 @@ package com.powsybl.dynawaltz.dsl.models.loads import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractSimpleEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -19,21 +19,21 @@ import com.powsybl.iidm.network.Network * @author Laurent Issertial */ @AutoService(DynamicModelGroovyExtension.class) -class LoadTwoTransformersGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class LoadTwoTransformersGroovyExtension extends AbstractSimpleEquipmentGroovyExtension { LoadTwoTransformersGroovyExtension() { super("LoadTwoTransformers") } @Override - protected LoadTwoTransformersBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { - new LoadTwoTransformersBuilder(network, equipmentConfig) + protected LoadTwoTransformersBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + new LoadTwoTransformersBuilder(network, equipmentConfig, reporter) } static class LoadTwoTransformersBuilder extends AbstractLoadModelBuilder { - LoadTwoTransformersBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig) + LoadTwoTransformersBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersTapChangersGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersTapChangersGroovyExtension.groovy index 7b67ad6af..0b1dd828f 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersTapChangersGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersTapChangersGroovyExtension.groovy @@ -8,7 +8,7 @@ package com.powsybl.dynawaltz.dsl.models.loads import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractSimpleEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -19,21 +19,21 @@ import com.powsybl.iidm.network.Network * @author Laurent Issertial */ @AutoService(DynamicModelGroovyExtension.class) -class LoadTwoTransformersTapChangersGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class LoadTwoTransformersTapChangersGroovyExtension extends AbstractSimpleEquipmentGroovyExtension { LoadTwoTransformersTapChangersGroovyExtension() { super("LoadTwoTransformersTapChangers") } @Override - protected LoadTwoTransformersTapChangersBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { - new LoadTwoTransformersTapChangersBuilder(network, equipmentConfig) + protected LoadTwoTransformersTapChangersBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + new LoadTwoTransformersTapChangersBuilder(network, equipmentConfig, reporter) } static class LoadTwoTransformersTapChangersBuilder extends AbstractLoadModelBuilder { - LoadTwoTransformersTapChangersBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig) + LoadTwoTransformersTapChangersBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/svarcs/SvarcGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/svarcs/SvarcGroovyExtension.groovy index fd247a4df..0d4373a9a 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/svarcs/SvarcGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/svarcs/SvarcGroovyExtension.groovy @@ -8,7 +8,7 @@ package com.powsybl.dynawaltz.dsl.models.svarcs import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.builders.AbstractEquipmentModelBuilder import com.powsybl.dynawaltz.models.svarcs.StaticVarCompensator as DynamicSvarc @@ -22,7 +22,7 @@ import com.powsybl.iidm.network.StaticVarCompensator as StaticSvarc * @author Laurent Issertial */ @AutoService(DynamicModelGroovyExtension.class) -class SvarcGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class SvarcGroovyExtension extends AbstractEquipmentGroovyExtension { protected static final String SVARC = "staticVarCompensators" @@ -31,14 +31,14 @@ class SvarcGroovyExtension extends AbstractEquipmentGroovyExtension { - SvcBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig, IdentifiableType.STATIC_VAR_COMPENSATOR) + SvcBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, IdentifiableType.STATIC_VAR_COMPENSATOR, reporter) } @Override diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/transformers/TransformerFixedRatioGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/transformers/TransformerFixedRatioGroovyExtension.groovy index ba19e881e..769ee3d77 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/transformers/TransformerFixedRatioGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/transformers/TransformerFixedRatioGroovyExtension.groovy @@ -8,7 +8,7 @@ package com.powsybl.dynawaltz.dsl.models.transformers import com.google.auto.service.AutoService -import com.powsybl.dynamicsimulation.DynamicModel +import com.powsybl.commons.reporter.Reporter import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.EquipmentConfig @@ -22,7 +22,7 @@ import com.powsybl.iidm.network.TwoWindingsTransformer * @author Laurent Issertial */ @AutoService(DynamicModelGroovyExtension.class) -class TransformerFixedRatioGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class TransformerFixedRatioGroovyExtension extends AbstractEquipmentGroovyExtension { private static final String TRANSFORMERS = "transformers" @@ -31,14 +31,14 @@ class TransformerFixedRatioGroovyExtension extends AbstractEquipmentGroovyExtens } @Override - protected TransformerBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { - new TransformerBuilder(network, equipmentConfig) + protected TransformerBuilder createBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + new TransformerBuilder(network, equipmentConfig, reporter) } static class TransformerBuilder extends AbstractEquipmentModelBuilder { - TransformerBuilder(Network network, EquipmentConfig equipmentConfig) { - super(network, equipmentConfig, IdentifiableType.TWO_WINDINGS_TRANSFORMER) + TransformerBuilder(Network network, EquipmentConfig equipmentConfig, Reporter reporter) { + super(network, equipmentConfig, IdentifiableType.TWO_WINDINGS_TRANSFORMER, reporter) } @Override diff --git a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/AbstractModelSupplierTest.java b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/AbstractModelSupplierTest.java index 2ecd28eab..adf182f61 100644 --- a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/AbstractModelSupplierTest.java +++ b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/AbstractModelSupplierTest.java @@ -7,15 +7,28 @@ */ package com.powsybl.dynawaltz.dsl; +import com.powsybl.commons.reporter.ReporterModel; + import java.io.InputStream; +import java.io.StringWriter; import java.util.Objects; +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * @author Laurent Issertial */ abstract class AbstractModelSupplierTest { + protected final ReporterModel reporter = new ReporterModel("dslTests", "DSL tests"); + protected InputStream getResourceAsStream(String name) { return Objects.requireNonNull(AbstractModelSupplierTest.class.getResourceAsStream(name)); } + + protected void checkReporter(String report) { + StringWriter sw = new StringWriter(); + reporter.export(sw); + assertEquals(report, sw.toString()); + } } diff --git a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java index c4e0d9a7c..92fdecfa2 100644 --- a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java +++ b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java @@ -74,19 +74,22 @@ void testAutomatonDynamicModels(String groovyScriptName, Class modelClass, Network network, String terminalVarName) { + void testGeneratorPrefixes(String groovyScriptName, Class modelClass, Network network, String terminalVarName, String report) { DynamicModelsSupplier supplier = new GroovyDynamicModelsSupplier(getResourceAsStream(groovyScriptName), EXTENSIONS); - List dynamicModels = supplier.get(network); + List dynamicModels = supplier.get(network, reporter); assertEquals(1, dynamicModels.size()); assertTrue(modelClass.isInstance(dynamicModels.get(0))); assertEquals(terminalVarName, modelClass.cast(dynamicModels.get(0)).getTerminalVarName()); + checkReporter(report); + } void assertEquipmentBlackBoxModel(EquipmentBlackBoxModel bbm, String dynamicId, String staticId, String parameterId, String lib) { @@ -144,27 +147,142 @@ private static Stream provideAutomatonModelData() { private static Stream provideWarningsModel() { return Stream.of( - Arguments.of("/warnings/missingStaticId.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/warnings/missingParameterId.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/warnings/missingEquipment.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/warnings/missingDangling.groovy", HvdcTestNetwork.createVsc()), - Arguments.of("/warnings/missingDanglingProperty.groovy", HvdcTestNetwork.createVsc()), - Arguments.of("/warnings/underVoltageMissingGenerator.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/warnings/phaseShifterMissingTransformer.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/warnings/claMissingMeasurement.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/warnings/claMissingMeasurementSide.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/warnings/claMissingControlled.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/warnings/cla2MissingMeasurement2.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/warnings/cla2MissingMeasurementSide2.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/warnings/tapChangerMissingBus.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/warnings/tapChangerCompatible.groovy", EurostagTutorialExample1Factory.create()) + Arguments.of("/warnings/missingStaticId.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for LoadAlphaBeta + 'staticId' field is not set + 'dynamicModelId' field is not set, staticId (unknown staticId) will be used instead + Model cannot be instantiated + """), + Arguments.of("/warnings/missingParameterId.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for LoadAlphaBeta + 'parameterSetId' field is not set + 'dynamicModelId' field is not set, staticId LOAD will be used instead + Model cannot be instantiated + """), + Arguments.of("/warnings/missingEquipment.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for LoadAlphaBeta + 'staticId' field value 'GEN' not found for equipment type(s) LOAD + 'dynamicModelId' field is not set, staticId GEN will be used instead + Model cannot be instantiated + """), + Arguments.of("/warnings/missingDangling.groovy", HvdcTestNetwork.createVsc(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for HvdcPVDangling + 'dangling' field is not set + Model cannot be instantiated + """), + Arguments.of("/warnings/missingDanglingProperty.groovy", HvdcTestNetwork.createVsc(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for HvdcPV + 'dangling' field is set but HvdcPV does not possess this option + Model cannot be instantiated + """), + Arguments.of("/warnings/underVoltageMissingGenerator.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for UnderVoltage + 'generator' field value 'NGEN' not found for equipment type(s) GENERATOR + Model cannot be instantiated + """), + Arguments.of("/warnings/phaseShifterMissingTransformer.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for PhaseShifterI + 'transformer' field value 'NGEN' not found for equipment type(s) TWO_WINDINGS_TRANSFORMER + Model cannot be instantiated + """), + Arguments.of("/warnings/claMissingMeasurement.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for CurrentLimitAutomaton + 'iMeasurement' field value 'NGEN' not found for equipment type(s) Quadripole + Model cannot be instantiated + """), + Arguments.of("/warnings/claMissingMeasurementSide.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for CurrentLimitAutomaton + 'iMeasurementSide' field is not set + Model cannot be instantiated + """), + Arguments.of("/warnings/claMissingControlled.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for CurrentLimitAutomaton + 'controlledQuadripole' field value 'GEN' not found for equipment type(s) Quadripole + Model cannot be instantiated + """), + Arguments.of("/warnings/cla2MissingMeasurement2.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for CurrentLimitAutomatonTwoLevels + 'iMeasurement2' field value 'NGEN' not found for equipment type(s) Quadripole + Model cannot be instantiated + """), + Arguments.of("/warnings/cla2MissingMeasurementSide2.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for CurrentLimitAutomatonTwoLevels + 'iMeasurement2Side' field is not set + Model cannot be instantiated + """), + Arguments.of("/warnings/tapChangerMissingBus.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for TapChangerBlockingAutomaton + 'uMeasurements' field value 'LOAD' not found for equipment type(s) BUS + 'uMeasurements' list is empty + Model cannot be instantiated + """), + Arguments.of("/warnings/tapChangerCompatible.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for TapChangerBlockingAutomaton + 'uMeasurements' field value 'GEN' not found for equipment type(s) LOAD/TWO_WINDINGS_TRANSFORMER + 'transformers' list is empty + Model cannot be instantiated + """) ); } private static Stream provideGenerator() { return Stream.of( - Arguments.of("/dynamicModels/gen.groovy", SynchronousGenerator.class, EurostagTutorialExample1Factory.create(), "generator_terminal"), - Arguments.of("/dynamicModels/genTfo.groovy", SynchronousGenerator.class, EurostagTutorialExample1Factory.create(), "transformer_terminal1") + Arguments.of("/dynamicModels/gen.groovy", SynchronousGenerator.class, EurostagTutorialExample1Factory.create(), "generator_terminal", + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for GeneratorSynchronousThreeWindings + Instantiation successful + """), + Arguments.of("/dynamicModels/genTfo.groovy", SynchronousGenerator.class, EurostagTutorialExample1Factory.create(), "transformer_terminal1", + """ + + DSL tests + + Groovy Dynamic Models Supplier + + DSL model builder for GeneratorSynchronousThreeWindingsPmConstVRNordicTfo + Instantiation successful + """) ); } } diff --git a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java index 15820e0e7..6799f3a9f 100644 --- a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java +++ b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java @@ -18,6 +18,7 @@ import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; import com.powsybl.iidm.network.test.HvdcTestNetwork; +import com.powsybl.iidm.network.test.SvcTestCaseFactory; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -46,9 +47,10 @@ void testEventModels(String groovyScriptName, Class mod @ParameterizedTest(name = "{0}") @MethodSource("provideWarningsModel") - void testDslWarnings(String groovyScriptName, Network network) { + void testDslWarnings(String groovyScriptName, Network network, String report) { EventModelsSupplier supplier = new GroovyEventModelsSupplier(getResourceAsStream(groovyScriptName), EXTENSIONS); - assertTrue(supplier.get(network).isEmpty()); + assertTrue(supplier.get(network, reporter).isEmpty()); + checkReporter(report); } void assertEventModel(AbstractEvent em, String dynamicId, String equipmentStaticId, String lib, double startTime) { @@ -76,12 +78,55 @@ private static Stream provideEventModelData() { private static Stream provideWarningsModel() { return Stream.of( - Arguments.of("/eventWarnings/missingStaticId.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/eventWarnings/missingStartTime.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/eventWarnings/missingNodeFaultParameters.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/eventWarnings/missingAPVParameters.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/eventWarnings/missingDisconnectionEquipment.groovy", EurostagTutorialExample1Factory.create()), - Arguments.of("/eventWarnings/missingDisconnectionSide.groovy", EurostagTutorialExample1Factory.create()) + Arguments.of("/eventWarnings/missingStaticId.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Event Models Supplier + + DSL model builder for NodeFault + 'staticId' field value 'GEN' not found for equipment type(s) BUS + Model cannot be instantiated + """), + Arguments.of("/eventWarnings/missingStartTime.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Event Models Supplier + + DSL model builder for NodeFault + 'startTime' field is not set + Model cannot be instantiated + """), + Arguments.of("/eventWarnings/missingNodeFaultParameters.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Event Models Supplier + + DSL model builder for NodeFault + faultTime should be strictly positive (0.0) + Model cannot be instantiated + """), + Arguments.of("/eventWarnings/missingAPVParameters.groovy", SvcTestCaseFactory.create(), + """ + + DSL tests + + Groovy Event Models Supplier + + DSL model builder for Step + 'staticId' field value 'SVC2' not found for equipment type(s) GENERATOR/LOAD + 'deltaP' field is not set + Model cannot be instantiated + """), + Arguments.of("/eventWarnings/missingDisconnectionEquipment.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Event Models Supplier + + DSL model builder for Disconnect + 'staticId' field value 'NGEN' not found for equipment type(s) Disconnectable equipment + Model cannot be instantiated + """), + Arguments.of("/eventWarnings/missingDisconnectionSide.groovy", EurostagTutorialExample1Factory.create(), + """ + + DSL tests + + Groovy Event Models Supplier + + DSL model builder for Disconnect + 'disconnectSide' field is set but GENERATOR GEN does not possess this option + Model cannot be instantiated + """) ); } } diff --git a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/ieee/AbstractIeeeTest.java b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/ieee/AbstractIeeeTest.java index 90adebf3c..1e55d317d 100644 --- a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/ieee/AbstractIeeeTest.java +++ b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/ieee/AbstractIeeeTest.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.concurrent.ForkJoinPool; +import static com.powsybl.commons.reporter.Reporter.NO_OP; import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -69,7 +70,7 @@ protected void setup(String parametersFile, String networkParametersFile, String List dynamicModelGroovyExtensions = GroovyExtension.find(DynamicModelGroovyExtension.class, DynaWaltzProvider.NAME); dynamicModelsSupplier = new GroovyDynamicModelsSupplier(workingDir.resolve("dynamicModels.groovy"), dynamicModelGroovyExtensions); } else { - dynamicModelsSupplier = n -> Collections.emptyList(); + dynamicModelsSupplier = (n, NO_OP) -> Collections.emptyList(); } // Event models @@ -115,7 +116,7 @@ public DynamicSimulationResult runSimulation(LocalCommandExecutor commandExecuto assertEquals(DynaWaltzProvider.NAME, dynawoSimulation.getName()); return dynawoSimulation.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, network.getVariantManager().getWorkingVariantId(), - computationManager, parameters); + computationManager, parameters, NO_OP); } } diff --git a/dynawaltz-dsl/src/test/resources/eventWarnings/missingAPVParameters.groovy b/dynawaltz-dsl/src/test/resources/eventWarnings/missingAPVParameters.groovy index 7c95a02fd..94afd90f9 100644 --- a/dynawaltz-dsl/src/test/resources/eventWarnings/missingAPVParameters.groovy +++ b/dynawaltz-dsl/src/test/resources/eventWarnings/missingAPVParameters.groovy @@ -9,6 +9,6 @@ package eventWarnings Step { - staticId "NGEN" + staticId "SVC2" startTime 2 } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index 1b041dd3f..e0656de43 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -9,6 +9,7 @@ import com.google.auto.service.AutoService; import com.powsybl.commons.config.PlatformConfig; import com.powsybl.commons.exceptions.UncheckedXmlStreamException; +import com.powsybl.commons.reporter.Reporter; import com.powsybl.computation.*; import com.powsybl.dynamicsimulation.*; import com.powsybl.dynawaltz.models.BlackBoxModel; @@ -101,14 +102,15 @@ private static String getProgram(DynaWaltzConfig dynaWaltzConfig) { @Override public CompletableFuture run(Network network, DynamicModelsSupplier dynamicModelsSupplier, EventModelsSupplier eventModelsSupplier, CurvesSupplier curvesSupplier, String workingVariantId, - ComputationManager computationManager, DynamicSimulationParameters parameters) { + ComputationManager computationManager, DynamicSimulationParameters parameters, Reporter reporter) { Objects.requireNonNull(dynamicModelsSupplier); Objects.requireNonNull(eventModelsSupplier); Objects.requireNonNull(curvesSupplier); Objects.requireNonNull(workingVariantId); Objects.requireNonNull(parameters); + Objects.requireNonNull(reporter); DynaWaltzParameters dynaWaltzParameters = getDynaWaltzSimulationParameters(parameters); - return run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, workingVariantId, computationManager, parameters, dynaWaltzParameters); + return run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, workingVariantId, computationManager, parameters, dynaWaltzParameters, reporter); } private DynaWaltzParameters getDynaWaltzSimulationParameters(DynamicSimulationParameters parameters) { @@ -120,22 +122,22 @@ private DynaWaltzParameters getDynaWaltzSimulationParameters(DynamicSimulationPa } private CompletableFuture run(Network network, DynamicModelsSupplier dynamicModelsSupplier, EventModelsSupplier eventsModelsSupplier, CurvesSupplier curvesSupplier, - String workingVariantId, ComputationManager computationManager, DynamicSimulationParameters parameters, DynaWaltzParameters dynaWaltzParameters) { + String workingVariantId, ComputationManager computationManager, DynamicSimulationParameters parameters, DynaWaltzParameters dynaWaltzParameters, Reporter reporter) { network.getVariantManager().setWorkingVariant(workingVariantId); ExecutionEnvironment execEnv = new ExecutionEnvironment(Collections.emptyMap(), WORKING_DIR_PREFIX, dynaWaltzConfig.isDebug()); Command versionCmd = getVersionCommand(dynaWaltzConfig); DynawoUtil.requireDynawoMinVersion(execEnv, computationManager, versionCmd, false); - List blackBoxModels = dynamicModelsSupplier.get(network).stream() + List blackBoxModels = dynamicModelsSupplier.get(network, reporter).stream() .filter(BlackBoxModel.class::isInstance) .map(BlackBoxModel.class::cast) .collect(Collectors.toList()); - List blackBoxEventModels = eventsModelsSupplier.get(network).stream() + List blackBoxEventModels = eventsModelsSupplier.get(network, reporter).stream() .filter(BlackBoxModel.class::isInstance) .map(BlackBoxModel.class::cast) .collect(Collectors.toList()); - DynaWaltzContext context = new DynaWaltzContext(network, workingVariantId, blackBoxModels, blackBoxEventModels, curvesSupplier.get(network), parameters, dynaWaltzParameters); + DynaWaltzContext context = new DynaWaltzContext(network, workingVariantId, blackBoxModels, blackBoxEventModels, curvesSupplier.get(network, reporter), parameters, dynaWaltzParameters); return computationManager.execute(execEnv, new DynaWaltzHandler(context)); } diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/DynaWaltzProviderTest.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/DynaWaltzProviderTest.java index 7a9064093..88f8c68c4 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/DynaWaltzProviderTest.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/DynaWaltzProviderTest.java @@ -7,6 +7,7 @@ package com.powsybl.dynawaltz; import com.powsybl.commons.PowsyblException; +import com.powsybl.commons.reporter.Reporter; import com.powsybl.commons.test.AbstractConverterTest; import com.powsybl.computation.ComputationManager; import com.powsybl.computation.local.LocalCommandExecutor; @@ -30,6 +31,7 @@ import java.util.Map; import java.util.concurrent.ForkJoinPool; +import static com.powsybl.commons.reporter.Reporter.NO_OP; import static org.junit.jupiter.api.Assertions.*; /** @@ -50,7 +52,7 @@ public void setUp() throws IOException { public static class CurvesSupplierMock implements CurvesSupplier { @Override - public List get(Network network) { + public List get(Network network, Reporter reporter) { return Collections.singletonList(new DynaWaltzCurve("bus", "uPu")); } } @@ -85,9 +87,9 @@ void testWithMergeLoads() throws Exception { ComputationManager computationManager = new LocalComputationManager(new LocalComputationConfig(tmpDir, 1), commandExecutor, ForkJoinPool.commonPool()); DynamicSimulation.Runner dynawoSimulation = DynamicSimulation.find(); assertEquals(DynaWaltzProvider.NAME, dynawoSimulation.getName()); - DynamicSimulationResult result = dynawoSimulation.run(network, n -> Collections.emptyList(), EventModelsSupplier.empty(), + DynamicSimulationResult result = dynawoSimulation.run(network, (n, NO_OP) -> Collections.emptyList(), EventModelsSupplier.empty(), CurvesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), - computationManager, DynamicSimulationParameters.load()); + computationManager, DynamicSimulationParameters.load(), NO_OP); assertNotNull(result); } @@ -103,9 +105,9 @@ void testWithoutMergeLoads() throws Exception { dynamicSimulationParameters.addExtension(DynaWaltzParameters.class, dynaWaltzParameters); assertEquals(DynaWaltzProvider.NAME, dynawoSimulation.getName()); - DynamicSimulationResult result = dynawoSimulation.run(network, n -> Collections.emptyList(), EventModelsSupplier.empty(), + DynamicSimulationResult result = dynawoSimulation.run(network, (n, NO_OP) -> Collections.emptyList(), EventModelsSupplier.empty(), CurvesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), - computationManager, dynamicSimulationParameters); + computationManager, dynamicSimulationParameters, NO_OP); assertNotNull(result); } @@ -116,9 +118,9 @@ void testFail() throws Exception { ComputationManager computationManager = new LocalComputationManager(new LocalComputationConfig(tmpDir, 1), commandExecutor, ForkJoinPool.commonPool()); DynamicSimulation.Runner dynawoSimulation = DynamicSimulation.find(); assertEquals(DynaWaltzProvider.NAME, dynawoSimulation.getName()); - DynamicSimulationResult result = dynawoSimulation.run(network, n -> Collections.emptyList(), EventModelsSupplier.empty(), + DynamicSimulationResult result = dynawoSimulation.run(network, (n, NO_OP) -> Collections.emptyList(), EventModelsSupplier.empty(), CurvesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), - computationManager, DynamicSimulationParameters.load()); + computationManager, DynamicSimulationParameters.load(), NO_OP); assertNotNull(result); assertFalse(result.isOk()); } @@ -130,9 +132,9 @@ void testWithoutCurves() throws Exception { ComputationManager computationManager = new LocalComputationManager(new LocalComputationConfig(tmpDir, 1), commandExecutor, ForkJoinPool.commonPool()); DynamicSimulation.Runner dynawoSimulation = DynamicSimulation.find(); assertEquals(DynaWaltzProvider.NAME, dynawoSimulation.getName()); - DynamicSimulationResult result = dynawoSimulation.run(network, n -> Collections.emptyList(), EventModelsSupplier.empty(), + DynamicSimulationResult result = dynawoSimulation.run(network, (n, NO_OP) -> Collections.emptyList(), EventModelsSupplier.empty(), new CurvesSupplierMock(), network.getVariantManager().getWorkingVariantId(), - computationManager, DynamicSimulationParameters.load()); + computationManager, DynamicSimulationParameters.load(), NO_OP); assertNotNull(result); assertFalse(result.isOk()); } @@ -164,12 +166,12 @@ void testCallingBadVersionDynawo() throws Exception { ComputationManager computationManager = new LocalComputationManager(new LocalComputationConfig(tmpDir, 1), commandExecutor, ForkJoinPool.commonPool()); DynamicSimulation.Runner dynawoSimulation = DynamicSimulation.find(); assertEquals(DynaWaltzProvider.NAME, dynawoSimulation.getName()); - DynamicModelsSupplier dms = n -> Collections.emptyList(); + DynamicModelsSupplier dms = (n, NO_OP) -> Collections.emptyList(); EventModelsSupplier ems = EventModelsSupplier.empty(); CurvesSupplier cs = CurvesSupplier.empty(); String wvId = network.getVariantManager().getWorkingVariantId(); DynamicSimulationParameters dsp = DynamicSimulationParameters.load(); - assertThrows(PowsyblException.class, () -> dynawoSimulation.run(network, dms, ems, cs, wvId, computationManager, dsp)); + assertThrows(PowsyblException.class, () -> dynawoSimulation.run(network, dms, ems, cs, wvId, computationManager, dsp, NO_OP)); } private static Network createTestNetwork() { diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java index 929c3bab4..998078181 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java @@ -25,6 +25,7 @@ import java.util.List; +import static com.powsybl.commons.reporter.Reporter.NO_OP; import static org.junit.jupiter.api.Assertions.*; /** @@ -75,7 +76,7 @@ void testIeee14() { .setSolverType(DynaWaltzParameters.SolverType.IDA); DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, - VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters) + VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); assertTrue(result.isOk()); @@ -105,7 +106,7 @@ void testSvc() { .setSolverType(DynaWaltzParameters.SolverType.IDA); DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, EventModelsSupplier.empty(), CurvesSupplier.empty(), - VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters) + VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); assertTrue(result.isOk()); @@ -132,7 +133,7 @@ void testHvdc() { .setSolverType(DynaWaltzParameters.SolverType.IDA); DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, EventModelsSupplier.empty(), CurvesSupplier.empty(), - VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters) + VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); assertTrue(result.isOk()); @@ -168,7 +169,7 @@ void testSmib() { .setWriteFinalState(false); DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, - VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters) + VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); assertTrue(result.isOk()); diff --git a/dynawo-integration-tests/src/test/resources/hvdc/models.par b/dynawo-integration-tests/src/test/resources/hvdc/models.par index 2519d5884..d4c322cae 100644 --- a/dynawo-integration-tests/src/test/resources/hvdc/models.par +++ b/dynawo-integration-tests/src/test/resources/hvdc/models.par @@ -17,6 +17,8 @@ + + diff --git a/pom.xml b/pom.xml index 5581048d2..33fd52243 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 17 - 6.0.0 + 6.1.0-SNAPSHOT 4.0.14 ../distribution/target/site/jacoco-aggregate/jacoco.xml, From 49972997e2eeac159c6650bbf2d89c664c4dae74 Mon Sep 17 00:00:00 2001 From: lisrte Date: Thu, 19 Oct 2023 15:43:31 +0200 Subject: [PATCH 02/20] Replace dynawaltz logger with reporter Signed-off-by: lisrte --- .../powsybl/dynawaltz/DynaWaltzContext.java | 25 +++++-- .../powsybl/dynawaltz/DynaWaltzProvider.java | 7 +- .../powsybl/dynawaltz/DynawaltzReports.java | 71 +++++++++++++++++++ .../automatons/TapChangerAutomaton.java | 7 +- .../TapChangerBlockingAutomaton.java | 6 +- 5 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 dynawaltz/src/main/java/com/powsybl/dynawaltz/DynawaltzReports.java diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java index 608d940ee..087755c45 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java @@ -7,6 +7,7 @@ package com.powsybl.dynawaltz; import com.powsybl.commons.PowsyblException; +import com.powsybl.commons.reporter.Reporter; import com.powsybl.dynamicsimulation.Curve; import com.powsybl.dynamicsimulation.DynamicSimulationParameters; import com.powsybl.dynawaltz.models.*; @@ -44,6 +45,7 @@ public class DynaWaltzContext { private static final String MODEL_ID_EXCEPTION = "The model identified by the static id %s does not match the expected model (%s)"; private static final String MODEL_ID_LOG = "The model identified by the static id {} does not match the expected model ({})"; + private final Reporter reporter; private final Network network; private final String workingVariantId; private final DynamicSimulationParameters parameters; @@ -61,13 +63,20 @@ public class DynaWaltzContext { public DynaWaltzContext(Network network, String workingVariantId, List dynamicModels, List eventModels, List curves, DynamicSimulationParameters parameters, DynaWaltzParameters dynaWaltzParameters) { + this(network, workingVariantId, dynamicModels, eventModels, curves, parameters, dynaWaltzParameters, Reporter.NO_OP); + } + + public DynaWaltzContext(Network network, String workingVariantId, List dynamicModels, List eventModels, + List curves, DynamicSimulationParameters parameters, DynaWaltzParameters dynaWaltzParameters, Reporter reporter) { + + this.reporter = DynawaltzReports.createDynaWaltzContextReporter(reporter); this.network = Objects.requireNonNull(network); this.workingVariantId = Objects.requireNonNull(workingVariantId); this.dynamicModels = Objects.requireNonNull(dynamicModels).stream() - .filter(distinctByDynamicId().and(distinctByStaticId())) + .filter(distinctByDynamicId(reporter).and(distinctByStaticId(reporter))) .toList(); this.eventModels = Objects.requireNonNull(eventModels).stream() - .filter(distinctByDynamicId()) + .filter(distinctByDynamicId(reporter)) .toList(); this.staticIdBlackBoxModelMap = getInputBlackBoxDynamicModelStream() .filter(EquipmentBlackBoxModel.class::isInstance) @@ -184,22 +193,22 @@ public EquipmentConnectionPoint getConnectionPointDynamicModel(String staticId) throw new PowsyblException(String.format(MODEL_ID_EXCEPTION, staticId, "ConnectionPoint")); } - protected static Predicate distinctByStaticId() { + protected static Predicate distinctByStaticId(Reporter reporter) { Set seen = new HashSet<>(); return bbm -> { if (bbm instanceof EquipmentBlackBoxModel eBbm && !seen.add(eBbm.getStaticId())) { - LOGGER.warn("Duplicate static id found: {} -> dynamic model {} {} will be skipped", eBbm.getStaticId(), eBbm.getLib(), eBbm.getDynamicModelId()); + DynawaltzReports.reportDuplicateStaticId(reporter, eBbm.getStaticId(), eBbm.getLib(), eBbm.getDynamicModelId()); return false; } return true; }; } - protected static Predicate distinctByDynamicId() { + protected static Predicate distinctByDynamicId(Reporter reporter) { Set seen = new HashSet<>(); return bbm -> { if (!seen.add(bbm.getDynamicModelId())) { - LOGGER.warn("Duplicate dynamic id found: {} -> model {} will be skipped", bbm.getDynamicModelId(), bbm.getName()); + DynawaltzReports.reportDuplicateDynamicId(reporter, bbm.getDynamicModelId(), bbm.getName()); return false; } return true; @@ -283,4 +292,8 @@ public List getDynamicModelsParameters() { public String getSimulationParFile() { return getNetwork().getId() + ".par"; } + + public Reporter getReporter() { + return reporter; + } } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index e0656de43..7f7f93f3a 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -124,20 +124,21 @@ private DynaWaltzParameters getDynaWaltzSimulationParameters(DynamicSimulationPa private CompletableFuture run(Network network, DynamicModelsSupplier dynamicModelsSupplier, EventModelsSupplier eventsModelsSupplier, CurvesSupplier curvesSupplier, String workingVariantId, ComputationManager computationManager, DynamicSimulationParameters parameters, DynaWaltzParameters dynaWaltzParameters, Reporter reporter) { + Reporter dsReporter = DynawaltzReports.createDynaWaltzReporter(reporter, network.getId()); network.getVariantManager().setWorkingVariant(workingVariantId); ExecutionEnvironment execEnv = new ExecutionEnvironment(Collections.emptyMap(), WORKING_DIR_PREFIX, dynaWaltzConfig.isDebug()); Command versionCmd = getVersionCommand(dynaWaltzConfig); DynawoUtil.requireDynawoMinVersion(execEnv, computationManager, versionCmd, false); - List blackBoxModels = dynamicModelsSupplier.get(network, reporter).stream() + List blackBoxModels = dynamicModelsSupplier.get(network, dsReporter).stream() .filter(BlackBoxModel.class::isInstance) .map(BlackBoxModel.class::cast) .collect(Collectors.toList()); - List blackBoxEventModels = eventsModelsSupplier.get(network, reporter).stream() + List blackBoxEventModels = eventsModelsSupplier.get(network, dsReporter).stream() .filter(BlackBoxModel.class::isInstance) .map(BlackBoxModel.class::cast) .collect(Collectors.toList()); - DynaWaltzContext context = new DynaWaltzContext(network, workingVariantId, blackBoxModels, blackBoxEventModels, curvesSupplier.get(network, reporter), parameters, dynaWaltzParameters); + DynaWaltzContext context = new DynaWaltzContext(network, workingVariantId, blackBoxModels, blackBoxEventModels, curvesSupplier.get(network, dsReporter), parameters, dynaWaltzParameters, reporter); return computationManager.execute(execEnv, new DynaWaltzHandler(context)); } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynawaltzReports.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynawaltzReports.java new file mode 100644 index 000000000..e6aafb366 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynawaltzReports.java @@ -0,0 +1,71 @@ +/** + * 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/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.dynawaltz; + +import com.powsybl.commons.reporter.Report; +import com.powsybl.commons.reporter.Reporter; +import com.powsybl.commons.reporter.TypedValue; + +/** + * @author Laurent Issertial + */ +public final class DynawaltzReports { + + private DynawaltzReports() { + } + + public static Reporter createDynaWaltzReporter(Reporter reporter, String networkId) { + return reporter.createSubReporter("dynawaltz", + "Dynawaltz dynamic simulation on network '${networkId}'", + "networkId", networkId); + } + + public static Reporter createDynaWaltzContextReporter(Reporter reporter) { + return reporter.createSubReporter("dynawaltzContext", + "Dynawaltz models processing"); + } + + public static void reportDuplicateStaticId(Reporter reporter, String duplicateId, String modelName, String dynamicId) { + reporter.report(Report.builder() + .withKey("duplicateId") + .withDefaultMessage("Duplicate static id found: ${duplicateId} -> model ${modelName} ${dynamicId} will be skipped") + .withValue("duplicateId", duplicateId) + .withValue("modelName", modelName) + .withValue("dynamicId", dynamicId) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } + + public static void reportDuplicateDynamicId(Reporter reporter, String duplicateId, String modelName) { + reporter.report(Report.builder() + .withKey("duplicateId") + .withDefaultMessage("Duplicate dynamic id found: ${duplicateId} -> model ${modelName} will be skipped") + .withValue("duplicateId", duplicateId) + .withValue("modelName", modelName) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } + + public static void reportEmptyTapChanger(Reporter reporter, String dynamicId) { + reporter.report(Report.builder() + .withKey("emptyTC") + .withDefaultMessage("TapChangerAutomaton ${dynamicId} load does not possess a transformer, the automaton will be skipped") + .withValue("dynamicId", dynamicId) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } + + public static void reportEmptyTapChangerBlockingAutomaton(Reporter reporter, String dynamicId) { + reporter.report(Report.builder() + .withKey("emptyTCB") + .withDefaultMessage("None of TapChangerBlockingAutomaton {} equipments are TapChangerModel, the automaton will be skipped") + .withValue("dynamicId", dynamicId) + .withSeverity(TypedValue.WARN_SEVERITY) + .build()); + } +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/TapChangerAutomaton.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/TapChangerAutomaton.java index ee986c2bc..7a987c545 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/TapChangerAutomaton.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/TapChangerAutomaton.java @@ -8,14 +8,13 @@ package com.powsybl.dynawaltz.models.automatons; import com.powsybl.dynawaltz.DynaWaltzContext; +import com.powsybl.dynawaltz.DynawaltzReports; import com.powsybl.dynawaltz.models.AbstractPureDynamicBlackBoxModel; import com.powsybl.dynawaltz.models.TransformerSide; import com.powsybl.dynawaltz.models.VarConnection; import com.powsybl.dynawaltz.models.loads.LoadWithTransformers; import com.powsybl.dynawaltz.models.transformers.TapChangerModel; import com.powsybl.iidm.network.Load; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; @@ -27,8 +26,6 @@ */ public class TapChangerAutomaton extends AbstractPureDynamicBlackBoxModel implements TapChangerModel { - private static final Logger LOGGER = LoggerFactory.getLogger(TapChangerAutomaton.class); - private final Load load; private final TransformerSide side; @@ -66,7 +63,7 @@ public void createMacroConnections(DynaWaltzContext context) { boolean isSkipped = createMacroConnectionsOrSkip(load, LoadWithTransformers.class, this::getVarConnectionsWith, context); if (isSkipped) { connection = ConnectionState.NOT_CONNECTED; - LOGGER.warn("TapChangerAutomaton {} load does not possess a transformer, the automaton will be skipped", getDynamicModelId()); + DynawaltzReports.reportEmptyTapChanger(context.getReporter(), getDynamicModelId()); } else { connection = ConnectionState.CONNECTED; } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/TapChangerBlockingAutomaton.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/TapChangerBlockingAutomaton.java index ee1a9a9e0..5cc27cc71 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/TapChangerBlockingAutomaton.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automatons/TapChangerBlockingAutomaton.java @@ -9,6 +9,7 @@ import com.powsybl.commons.PowsyblException; import com.powsybl.dynawaltz.DynaWaltzContext; +import com.powsybl.dynawaltz.DynawaltzReports; import com.powsybl.dynawaltz.models.AbstractPureDynamicBlackBoxModel; import com.powsybl.dynawaltz.models.MeasurementPointSuffix; import com.powsybl.dynawaltz.models.VarConnection; @@ -18,8 +19,6 @@ import com.powsybl.iidm.network.IdentifiableType; import com.powsybl.iidm.network.Load; import com.powsybl.iidm.network.TwoWindingsTransformer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; @@ -30,7 +29,6 @@ */ public class TapChangerBlockingAutomaton extends AbstractPureDynamicBlackBoxModel { - private static final Logger LOGGER = LoggerFactory.getLogger(TapChangerBlockingAutomaton.class); private static final Set COMPATIBLE_EQUIPMENTS = EnumSet.of(IdentifiableType.LOAD, IdentifiableType.TWO_WINDINGS_TRANSFORMER); private static final int MAX_MEASUREMENTS = 5; @@ -104,7 +102,7 @@ public void createMacroConnections(DynaWaltzContext context) { } } else { isConnected = false; - LOGGER.warn("None of TapChangerBlockingAutomaton {} equipments are TapChangerModel, the automaton will be skipped", getDynamicModelId()); + DynawaltzReports.reportEmptyTapChangerBlockingAutomaton(context.getReporter(), getDynamicModelId()); } } From e930c0ed96a264814e0087c0e696423f260d4c86 Mon Sep 17 00:00:00 2001 From: lisrte Date: Thu, 19 Oct 2023 15:46:54 +0200 Subject: [PATCH 03/20] Remove unnecessary modification Signed-off-by: lisrte --- dynawo-integration-tests/src/test/resources/hvdc/models.par | 2 -- 1 file changed, 2 deletions(-) diff --git a/dynawo-integration-tests/src/test/resources/hvdc/models.par b/dynawo-integration-tests/src/test/resources/hvdc/models.par index d4c322cae..2519d5884 100644 --- a/dynawo-integration-tests/src/test/resources/hvdc/models.par +++ b/dynawo-integration-tests/src/test/resources/hvdc/models.par @@ -17,8 +17,6 @@ - - From 3daaea05e90a87d3aa18faff08d3dddb56ad5e88 Mon Sep 17 00:00:00 2001 From: lisrte Date: Mon, 23 Oct 2023 13:30:21 +0200 Subject: [PATCH 04/20] Add dynamic model ID to instantiation logs Signed-off-by: lisrte --- .../powsybl/dynawaltz/dsl/Reporters.groovy | 10 +++--- .../AbstractDynamicModelBuilder.groovy | 4 ++- .../AbstractEquipmentModelBuilder.groovy | 5 +++ .../builders/AbstractEventModelBuilder.groovy | 6 ++++ .../AbstractPureDynamicModelBuilder.groovy | 5 +++ .../dsl/DynamicModelsSupplierTest.java | 32 +++++++++---------- .../dsl/EventModelsSupplierTest.java | 12 +++---- .../models/events/AbstractEvent.java | 4 +-- 8 files changed, 49 insertions(+), 29 deletions(-) diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/Reporters.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/Reporters.groovy index 735d48608..8828e3961 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/Reporters.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/Reporters.groovy @@ -26,18 +26,20 @@ final class Reporters { "lib", lib) } - static void reportModelInstantiation(Reporter reporter) { + static void reportModelInstantiation(Reporter reporter, String dynamicId) { reporter.report(Report.builder() .withKey("modelInstantiation") - .withDefaultMessage('Instantiation successful') + .withDefaultMessage('Model ${dynamicId} instantiation successful') + .withValue("dynamicId", dynamicId) .withSeverity(TypedValue.TRACE_SEVERITY) .build()) } - static void reportModelInstantiationFailure(Reporter reporter) { + static void reportModelInstantiationFailure(Reporter reporter, String dynamicId) { reporter.report(Report.builder() .withKey("modelInstantiation") - .withDefaultMessage('Model cannot be instantiated') + .withDefaultMessage('Model ${dynamicId} cannot be instantiated') + .withValue("dynamicId", dynamicId) .withSeverity(TypedValue.WARN_SEVERITY) .build()) } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractDynamicModelBuilder.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractDynamicModelBuilder.groovy index e2fd61283..23f24f099 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractDynamicModelBuilder.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractDynamicModelBuilder.groovy @@ -34,7 +34,9 @@ abstract class AbstractDynamicModelBuilder { protected final boolean isInstantiable() { checkData() - isInstantiable ? Reporters.reportModelInstantiation(reporter) : Reporters.reportModelInstantiationFailure(reporter) + isInstantiable ? Reporters.reportModelInstantiation(reporter, getModelId()) : Reporters.reportModelInstantiationFailure(reporter, getModelId()) isInstantiable } + + abstract protected String getModelId() } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEquipmentModelBuilder.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEquipmentModelBuilder.groovy index d6681018b..c46cd1ed1 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEquipmentModelBuilder.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEquipmentModelBuilder.groovy @@ -64,6 +64,11 @@ abstract class AbstractEquipmentModelBuilder extends Abs dslEquipment.equipment } + @Override + String getModelId() { + dynamicModelId ?: "unknownDynamicId" + } + @Override abstract DynamicModel build() } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEventModelBuilder.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEventModelBuilder.groovy index 455f14a6f..06bd9998a 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEventModelBuilder.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractEventModelBuilder.groovy @@ -13,6 +13,7 @@ import com.powsybl.dynamicsimulation.EventModel import com.powsybl.dynawaltz.dsl.DslEquipment import com.powsybl.dynawaltz.dsl.ModelBuilder import com.powsybl.dynawaltz.dsl.Reporters +import com.powsybl.dynawaltz.models.events.AbstractEvent import com.powsybl.iidm.network.Identifiable import com.powsybl.iidm.network.Network @@ -51,6 +52,11 @@ abstract class AbstractEventModelBuilder extends Abstrac abstract protected Identifiable findEquipment(String staticId) + @Override + String getModelId() { + AbstractEvent.generateEventId(tag + "_", dslEquipment.staticId ?: "unknownStaticId") + } + @Override abstract EventModel build() } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractPureDynamicModelBuilder.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractPureDynamicModelBuilder.groovy index 1bd2f2388..c59e8d57e 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractPureDynamicModelBuilder.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/builders/AbstractPureDynamicModelBuilder.groovy @@ -47,6 +47,11 @@ abstract class AbstractPureDynamicModelBuilder extends AbstractDynamicModelBuild } } + @Override + String getModelId() { + dynamicModelId ?: "unknownDynamicId" + } + @Override abstract DynamicModel build() } diff --git a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java index 92fdecfa2..4d95a8eee 100644 --- a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java +++ b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java @@ -154,7 +154,7 @@ private static Stream provideWarningsModel() { + DSL model builder for LoadAlphaBeta 'staticId' field is not set 'dynamicModelId' field is not set, staticId (unknown staticId) will be used instead - Model cannot be instantiated + Model unknownDynamicId cannot be instantiated """), Arguments.of("/warnings/missingParameterId.groovy", EurostagTutorialExample1Factory.create(), """ @@ -163,7 +163,7 @@ private static Stream provideWarningsModel() { + DSL model builder for LoadAlphaBeta 'parameterSetId' field is not set 'dynamicModelId' field is not set, staticId LOAD will be used instead - Model cannot be instantiated + Model LOAD cannot be instantiated """), Arguments.of("/warnings/missingEquipment.groovy", EurostagTutorialExample1Factory.create(), """ @@ -172,7 +172,7 @@ private static Stream provideWarningsModel() { + DSL model builder for LoadAlphaBeta 'staticId' field value 'GEN' not found for equipment type(s) LOAD 'dynamicModelId' field is not set, staticId GEN will be used instead - Model cannot be instantiated + Model GEN cannot be instantiated """), Arguments.of("/warnings/missingDangling.groovy", HvdcTestNetwork.createVsc(), """ @@ -180,7 +180,7 @@ private static Stream provideWarningsModel() { + Groovy Dynamic Models Supplier + DSL model builder for HvdcPVDangling 'dangling' field is not set - Model cannot be instantiated + Model BBM_HVDC_L cannot be instantiated """), Arguments.of("/warnings/missingDanglingProperty.groovy", HvdcTestNetwork.createVsc(), """ @@ -188,7 +188,7 @@ private static Stream provideWarningsModel() { + Groovy Dynamic Models Supplier + DSL model builder for HvdcPV 'dangling' field is set but HvdcPV does not possess this option - Model cannot be instantiated + Model BBM_HVDC_L cannot be instantiated """), Arguments.of("/warnings/underVoltageMissingGenerator.groovy", EurostagTutorialExample1Factory.create(), """ @@ -196,7 +196,7 @@ private static Stream provideWarningsModel() { + Groovy Dynamic Models Supplier + DSL model builder for UnderVoltage 'generator' field value 'NGEN' not found for equipment type(s) GENERATOR - Model cannot be instantiated + Model UV_GEN cannot be instantiated """), Arguments.of("/warnings/phaseShifterMissingTransformer.groovy", EurostagTutorialExample1Factory.create(), """ @@ -204,7 +204,7 @@ private static Stream provideWarningsModel() { + Groovy Dynamic Models Supplier + DSL model builder for PhaseShifterI 'transformer' field value 'NGEN' not found for equipment type(s) TWO_WINDINGS_TRANSFORMER - Model cannot be instantiated + Model PS_NGEN_NHV1 cannot be instantiated """), Arguments.of("/warnings/claMissingMeasurement.groovy", EurostagTutorialExample1Factory.create(), """ @@ -212,7 +212,7 @@ private static Stream provideWarningsModel() { + Groovy Dynamic Models Supplier + DSL model builder for CurrentLimitAutomaton 'iMeasurement' field value 'NGEN' not found for equipment type(s) Quadripole - Model cannot be instantiated + Model CLA_NGEN cannot be instantiated """), Arguments.of("/warnings/claMissingMeasurementSide.groovy", EurostagTutorialExample1Factory.create(), """ @@ -220,7 +220,7 @@ private static Stream provideWarningsModel() { + Groovy Dynamic Models Supplier + DSL model builder for CurrentLimitAutomaton 'iMeasurementSide' field is not set - Model cannot be instantiated + Model CLA_NGEN cannot be instantiated """), Arguments.of("/warnings/claMissingControlled.groovy", EurostagTutorialExample1Factory.create(), """ @@ -228,7 +228,7 @@ private static Stream provideWarningsModel() { + Groovy Dynamic Models Supplier + DSL model builder for CurrentLimitAutomaton 'controlledQuadripole' field value 'GEN' not found for equipment type(s) Quadripole - Model cannot be instantiated + Model CLA_NGEN cannot be instantiated """), Arguments.of("/warnings/cla2MissingMeasurement2.groovy", EurostagTutorialExample1Factory.create(), """ @@ -236,7 +236,7 @@ private static Stream provideWarningsModel() { + Groovy Dynamic Models Supplier + DSL model builder for CurrentLimitAutomatonTwoLevels 'iMeasurement2' field value 'NGEN' not found for equipment type(s) Quadripole - Model cannot be instantiated + Model CLA_NGEN cannot be instantiated """), Arguments.of("/warnings/cla2MissingMeasurementSide2.groovy", EurostagTutorialExample1Factory.create(), """ @@ -244,7 +244,7 @@ private static Stream provideWarningsModel() { + Groovy Dynamic Models Supplier + DSL model builder for CurrentLimitAutomatonTwoLevels 'iMeasurement2Side' field is not set - Model cannot be instantiated + Model CLA_NGEN cannot be instantiated """), Arguments.of("/warnings/tapChangerMissingBus.groovy", EurostagTutorialExample1Factory.create(), """ @@ -253,7 +253,7 @@ private static Stream provideWarningsModel() { + DSL model builder for TapChangerBlockingAutomaton 'uMeasurements' field value 'LOAD' not found for equipment type(s) BUS 'uMeasurements' list is empty - Model cannot be instantiated + Model ZAB cannot be instantiated """), Arguments.of("/warnings/tapChangerCompatible.groovy", EurostagTutorialExample1Factory.create(), """ @@ -262,7 +262,7 @@ private static Stream provideWarningsModel() { + DSL model builder for TapChangerBlockingAutomaton 'uMeasurements' field value 'GEN' not found for equipment type(s) LOAD/TWO_WINDINGS_TRANSFORMER 'transformers' list is empty - Model cannot be instantiated + Model ZAB cannot be instantiated """) ); } @@ -274,14 +274,14 @@ private static Stream provideGenerator() { + DSL tests + Groovy Dynamic Models Supplier + DSL model builder for GeneratorSynchronousThreeWindings - Instantiation successful + Model BBM_GEN instantiation successful """), Arguments.of("/dynamicModels/genTfo.groovy", SynchronousGenerator.class, EurostagTutorialExample1Factory.create(), "transformer_terminal1", """ + DSL tests + Groovy Dynamic Models Supplier + DSL model builder for GeneratorSynchronousThreeWindingsPmConstVRNordicTfo - Instantiation successful + Model BBM_GEN instantiation successful """) ); } diff --git a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java index 6799f3a9f..fb7c3439a 100644 --- a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java +++ b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java @@ -84,7 +84,7 @@ private static Stream provideWarningsModel() { + Groovy Event Models Supplier + DSL model builder for NodeFault 'staticId' field value 'GEN' not found for equipment type(s) BUS - Model cannot be instantiated + Model NodeFault_GEN cannot be instantiated """), Arguments.of("/eventWarnings/missingStartTime.groovy", EurostagTutorialExample1Factory.create(), """ @@ -92,7 +92,7 @@ private static Stream provideWarningsModel() { + Groovy Event Models Supplier + DSL model builder for NodeFault 'startTime' field is not set - Model cannot be instantiated + Model NodeFault_NGEN cannot be instantiated """), Arguments.of("/eventWarnings/missingNodeFaultParameters.groovy", EurostagTutorialExample1Factory.create(), """ @@ -100,7 +100,7 @@ private static Stream provideWarningsModel() { + Groovy Event Models Supplier + DSL model builder for NodeFault faultTime should be strictly positive (0.0) - Model cannot be instantiated + Model NodeFault_NGEN cannot be instantiated """), Arguments.of("/eventWarnings/missingAPVParameters.groovy", SvcTestCaseFactory.create(), """ @@ -109,7 +109,7 @@ faultTime should be strictly positive (0.0) + DSL model builder for Step 'staticId' field value 'SVC2' not found for equipment type(s) GENERATOR/LOAD 'deltaP' field is not set - Model cannot be instantiated + Model Step_SVC2 cannot be instantiated """), Arguments.of("/eventWarnings/missingDisconnectionEquipment.groovy", EurostagTutorialExample1Factory.create(), """ @@ -117,7 +117,7 @@ faultTime should be strictly positive (0.0) + Groovy Event Models Supplier + DSL model builder for Disconnect 'staticId' field value 'NGEN' not found for equipment type(s) Disconnectable equipment - Model cannot be instantiated + Model Disconnect_NGEN cannot be instantiated """), Arguments.of("/eventWarnings/missingDisconnectionSide.groovy", EurostagTutorialExample1Factory.create(), """ @@ -125,7 +125,7 @@ faultTime should be strictly positive (0.0) + Groovy Event Models Supplier + DSL model builder for Disconnect 'disconnectSide' field is set but GENERATOR GEN does not possess this option - Model cannot be instantiated + Model Disconnect_GEN cannot be instantiated """) ); } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/AbstractEvent.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/AbstractEvent.java index d51d79372..2f37fcdd0 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/AbstractEvent.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/AbstractEvent.java @@ -25,12 +25,12 @@ public abstract class AbstractEvent extends AbstractPureDynamicBlackBoxModel imp private final double startTime; protected AbstractEvent(Identifiable equipment, double startTime, String eventPrefix) { - super(generateEventId(equipment.getId(), eventPrefix)); + super(generateEventId(eventPrefix, equipment.getId())); this.equipment = equipment; this.startTime = startTime; } - private static String generateEventId(String equipmentStaticId, String eventPrefix) { + public static String generateEventId(String eventPrefix, String equipmentStaticId) { return eventPrefix + equipmentStaticId; } From 50f482e90db3ff39d65315f001e670189450fd41 Mon Sep 17 00:00:00 2001 From: lisrte Date: Thu, 9 Nov 2023 14:49:26 +0100 Subject: [PATCH 05/20] config maven for correct powsybl-core sources Signed-off-by: lisrte --- .github/workflows/maven.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 909d4fa1b..e27a05402 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -17,6 +17,12 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] steps: + - name: Checkout powsybl-core linked sources + uses: actions/checkout@v1 + with: + repository: powsybl/powsybl-core + ref: refs/heads/dynamic_simulation_reporter + - name: Checkout sources uses: actions/checkout@v1 @@ -25,6 +31,9 @@ jobs: with: java-version: 17 + - name: Build and install powsybl-core with Maven + run: mvn --batch-mode -DskipTests=true --file ../powsybl-core/pom.xml install + - name: Build with Maven if: matrix.os == 'ubuntu-latest' run: mvn --batch-mode -Pintegration-tests,jacoco install From 62d5f88935a04f088d7a60ee944bfb4bfd4254c8 Mon Sep 17 00:00:00 2001 From: lisrte Date: Fri, 10 Nov 2023 11:17:03 +0100 Subject: [PATCH 06/20] fix rebase Signed-off-by: lisrte --- .../java/com/powsybl/dynawaltz/DynaWaltzProviderTest.java | 6 +++--- .../src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/DynaWaltzProviderTest.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/DynaWaltzProviderTest.java index 046276772..918a31fa2 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/DynaWaltzProviderTest.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/DynaWaltzProviderTest.java @@ -130,9 +130,9 @@ void testWithDump() throws Exception { dynamicSimulationParameters.addExtension(DynaWaltzParameters.class, dynaWaltzParameters); assertEquals(DynaWaltzProvider.NAME, dynawoSimulation.getName()); - DynamicSimulationResult result = dynawoSimulation.run(network, n -> Collections.emptyList(), EventModelsSupplier.empty(), + DynamicSimulationResult result = dynawoSimulation.run(network, (n, r) -> Collections.emptyList(), EventModelsSupplier.empty(), CurvesSupplier.empty(), network.getVariantManager().getWorkingVariantId(), - computationManager, dynamicSimulationParameters); + computationManager, dynamicSimulationParameters, NO_OP); assertNotNull(result); } @@ -196,7 +196,7 @@ void testCallingBadVersionDynawo() throws Exception { CurvesSupplier cs = CurvesSupplier.empty(); String wvId = network.getVariantManager().getWorkingVariantId(); DynamicSimulationParameters dsp = DynamicSimulationParameters.load(); - PowsyblException e = assertThrows(PowsyblException.class, () -> dynawoSimulation.run(network, dms, ems, cs, wvId, computationManager, dsp)); + PowsyblException e = assertThrows(PowsyblException.class, () -> dynawoSimulation.run(network, dms, ems, cs, wvId, computationManager, dsp, NO_OP)); assertEquals("dynawo version not supported. Must be >= " + DynawoConstants.VERSION_MIN, e.getMessage()); } diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java index b15d9433f..dc047fe6a 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java @@ -126,7 +126,7 @@ void testIeee14WithDump() throws IOException { .setDumpFileParameters(dumpFileParameters); DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, - VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters) + VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); assertTrue(result.isOk()); @@ -141,7 +141,7 @@ void testIeee14WithDump() throws IOException { dynaWaltzParameters.setDumpFileParameters(DumpFileParameters.createImportDumpFileParameters(dumpDir, dumpFile)); result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, - VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters) + VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); assertTrue(result.isOk()); From 7901f090855c31fc8b6063fcef4dba39027618cd Mon Sep 17 00:00:00 2001 From: lisrte Date: Fri, 10 Nov 2023 15:57:01 +0100 Subject: [PATCH 07/20] Add timeline to reporter and dynawo logs to DynamicSimulationResult to logs Add simulation error integration test Signed-off-by: lisrte --- .../powsybl/dynawo/commons/CommonReports.java | 36 + .../dynawo/commons/DynawoConstants.java | 2 + .../powsybl/dynaflow/DynaFlowConstants.java | 1 - .../powsybl/dynaflow/DynaFlowProvider.java | 4 +- .../dynaflow/DynaFlowSecurityAnalysis.java | 6 +- .../java/com/powsybl/dynaflow/Reports.java | 16 - .../powsybl/dynawaltz/DynaWaltzProvider.java | 58 +- .../powsybl/dynawaltz/DynawaltzReports.java | 5 + .../com/powsybl/dynawo/it/DynaWaltzTest.java | 24 + .../src/test/resources/error/models.groovy | 30 + .../src/test/resources/error/models.par | 1013 ++++++++ .../src/test/resources/error/network.par | 26 + .../resources/error/powsybl_dynawaltz.xiidm | 2195 +++++++++++++++++ .../src/test/resources/error/solvers.par | 10 + 14 files changed, 3390 insertions(+), 36 deletions(-) create mode 100644 commons/src/main/java/com/powsybl/dynawo/commons/CommonReports.java create mode 100644 dynawo-integration-tests/src/test/resources/error/models.groovy create mode 100644 dynawo-integration-tests/src/test/resources/error/models.par create mode 100644 dynawo-integration-tests/src/test/resources/error/network.par create mode 100644 dynawo-integration-tests/src/test/resources/error/powsybl_dynawaltz.xiidm create mode 100644 dynawo-integration-tests/src/test/resources/error/solvers.par diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/CommonReports.java b/commons/src/main/java/com/powsybl/dynawo/commons/CommonReports.java new file mode 100644 index 000000000..81d5b5206 --- /dev/null +++ b/commons/src/main/java/com/powsybl/dynawo/commons/CommonReports.java @@ -0,0 +1,36 @@ +/** + * 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/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.dynawo.commons; + +import com.powsybl.commons.reporter.Report; +import com.powsybl.commons.reporter.Reporter; +import com.powsybl.commons.reporter.TypedValue; +import com.powsybl.dynawo.commons.timeline.TimelineEntry; + +/** + * @author Laurent Issertial {@literal } + */ +public final class CommonReports { + + private static final String TIME_MS = "timeMsTypedValue"; + private static final String ID = "idTypedValue"; + + private CommonReports() { + } + + public static void reportTimelineEvent(Reporter reporter, TimelineEntry timelineEntry) { + reporter.report(Report.builder() + .withKey("DynawoTimelineEvent") + .withDefaultMessage("[t=${time}] ${message} on equipment '${identifiableId}'") + .withTypedValue("time", timelineEntry.time(), TIME_MS) + .withTypedValue("identifiableId", timelineEntry.modelName(), ID) + .withValue("message", timelineEntry.message()) + .withSeverity(TypedValue.TRACE_SEVERITY) + .build()); + } +} diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java b/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java index 25474862e..f75901811 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/DynawoConstants.java @@ -26,6 +26,8 @@ private DynawoConstants() { public static final String DYNAWO_CMD_NAME = "dynawo"; + public static final String DYNAWO_TIMELINE_FOLDER = "timeLine"; + public static final DynawoVersion VERSION_MIN = new DynawoVersion(1, 5, 0); public static final List IIDM_EXTENSIONS = List.of( diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowConstants.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowConstants.java index c20c23d41..79f7287a6 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowConstants.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowConstants.java @@ -21,7 +21,6 @@ public final class DynaFlowConstants { public static final String OUTPUT_IIDM_FILENAME = "outputIIDM.xml"; public static final String OUTPUT_RESULTS_FILENAME = "results.json"; static final String DYNAFLOW_OUTPUTS_FOLDER = "outputs"; - static final String DYNAWO_TIMELINE_FOLDER = "timeLine"; static final String DYNAFLOW_TIMELINE_FILE = "timeline.xml"; diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java index a5cfa4986..a3962d45d 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowProvider.java @@ -17,6 +17,7 @@ import com.powsybl.computation.*; import com.powsybl.dynaflow.json.DynaFlowConfigSerializer; import com.powsybl.dynaflow.json.JsonDynaFlowParametersSerializer; +import com.powsybl.dynawo.commons.CommonReports; import com.powsybl.dynawo.commons.DynawoUtil; import com.powsybl.dynawo.commons.NetworkResultsUpdater; import com.powsybl.dynawo.commons.PowsyblDynawoVersion; @@ -38,6 +39,7 @@ import java.util.concurrent.CompletableFuture; import static com.powsybl.dynaflow.DynaFlowConstants.*; +import static com.powsybl.dynawo.commons.DynawoConstants.DYNAWO_TIMELINE_FOLDER; /** * @@ -213,7 +215,7 @@ private void reportTimeLine(Path workingDir) { .resolve(DYNAWO_TIMELINE_FOLDER) .resolve(DYNAFLOW_TIMELINE_FILE); List tl = new XmlTimeLineParser().parse(timelineFile); - tl.forEach(e -> Reports.reportTimelineEvent(dfReporter, e)); + tl.forEach(e -> CommonReports.reportTimelineEvent(dfReporter, e)); } } } diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysis.java b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysis.java index efb09524f..431b03403 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysis.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/DynaFlowSecurityAnalysis.java @@ -17,6 +17,7 @@ import com.powsybl.contingency.json.ContingencyJsonModule; import com.powsybl.dynaflow.json.DynaFlowConfigSerializer; import com.powsybl.dynaflow.xml.ConstraintsReader; +import com.powsybl.dynawo.commons.CommonReports; import com.powsybl.dynawo.commons.DynawoUtil; import com.powsybl.dynawo.commons.timeline.TimelineEntry; import com.powsybl.dynawo.commons.timeline.XmlTimeLineParser; @@ -40,6 +41,7 @@ import static com.powsybl.dynaflow.DynaFlowConstants.CONFIG_FILENAME; import static com.powsybl.dynaflow.DynaFlowConstants.IIDM_FILENAME; +import static com.powsybl.dynawo.commons.DynawoConstants.DYNAWO_TIMELINE_FOLDER; /** * @author Luma Zamarreno {@literal } @@ -170,10 +172,10 @@ public SecurityAnalysisReport after(Path workingDir, ExecutionReport report) thr .toList(); // Report the timeline events from the timeline files written by dynawo - Path timelineDir = workingDir.resolve(DynaFlowConstants.DYNAWO_TIMELINE_FOLDER); + Path timelineDir = workingDir.resolve(DYNAWO_TIMELINE_FOLDER); contingencies.forEach(c -> { Reporter contingencyReporter = Reports.createDynaFlowTimelineReporter(reporter, c.getId()); - getTimeline(timelineDir, c).forEach(e -> Reports.reportTimelineEvent(contingencyReporter, e)); + getTimeline(timelineDir, c).forEach(e -> CommonReports.reportTimelineEvent(contingencyReporter, e)); }); return new SecurityAnalysisReport( diff --git a/dynaflow/src/main/java/com/powsybl/dynaflow/Reports.java b/dynaflow/src/main/java/com/powsybl/dynaflow/Reports.java index f4819f55d..c88b08fb3 100644 --- a/dynaflow/src/main/java/com/powsybl/dynaflow/Reports.java +++ b/dynaflow/src/main/java/com/powsybl/dynaflow/Reports.java @@ -7,17 +7,12 @@ */ package com.powsybl.dynaflow; -import com.powsybl.commons.reporter.Report; import com.powsybl.commons.reporter.Reporter; -import com.powsybl.commons.reporter.TypedValue; -import com.powsybl.dynawo.commons.timeline.TimelineEntry; /** * @author Florian Dupuy {@literal } */ public final class Reports { - private static final String TIME_MS = "timeMsTypedValue"; - private static final String ID = "idTypedValue"; private Reports() { } @@ -39,15 +34,4 @@ public static Reporter createDynaFlowTimelineReporter(Reporter reporter, String "Contingency '${contingencyId}'", "contingencyId", contingencyId); } - - public static void reportTimelineEvent(Reporter reporter, TimelineEntry timelineEntry) { - reporter.report(Report.builder() - .withKey("DynawoTimelineEvent") - .withDefaultMessage("[t=${time}] ${message} on equipment '${identifiableId}'") - .withTypedValue("time", timelineEntry.time(), TIME_MS) - .withTypedValue("identifiableId", timelineEntry.modelName(), ID) - .withValue("message", timelineEntry.message()) - .withSeverity(TypedValue.TRACE_SEVERITY) - .build()); - } } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index a0db33050..12cb6c0ba 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -17,11 +17,9 @@ import com.powsybl.dynawaltz.xml.DydXml; import com.powsybl.dynawaltz.xml.JobsXml; import com.powsybl.dynawaltz.xml.ParametersXml; -import com.powsybl.dynawo.commons.DynawoConstants; -import com.powsybl.dynawo.commons.DynawoUtil; -import com.powsybl.dynawo.commons.NetworkResultsUpdater; -import com.powsybl.dynawo.commons.PowsyblDynawoVersion; +import com.powsybl.dynawo.commons.*; import com.powsybl.dynawo.commons.loadmerge.LoadsMerger; +import com.powsybl.dynawo.commons.timeline.CsvTimeLineParser; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.xml.NetworkXml; import com.powsybl.timeseries.TimeSeries; @@ -42,6 +40,7 @@ import java.util.stream.Collectors; import static com.powsybl.dynawaltz.xml.DynaWaltzConstants.*; +import static com.powsybl.dynawo.commons.DynawoConstants.DYNAWO_TIMELINE_FOLDER; /** * @author Marcos de Miguel {@literal } @@ -54,8 +53,11 @@ public class DynaWaltzProvider implements DynamicSimulationProvider { private static final String OUTPUTS_FOLDER = "outputs"; private static final String FINAL_STATE_FOLDER = "finalState"; + private static final String LOGS_FOLDER = "logs"; private static final String OUTPUT_IIDM_FILENAME = "outputIIDM.xml"; private static final String OUTPUT_DUMP_FILENAME = "outputState.dmp"; + private static final String TIMELINE_FILENAME = "timeline.log"; + private static final String LOGS_FILENAME = "dynawaltz.log"; private static final Logger LOGGER = LoggerFactory.getLogger(DynaWaltzProvider.class); @@ -141,19 +143,21 @@ private CompletableFuture run(Network network, DynamicM .map(BlackBoxModel.class::cast) .collect(Collectors.toList()); DynaWaltzContext context = new DynaWaltzContext(network, workingVariantId, blackBoxModels, blackBoxEventModels, curvesSupplier.get(network, dsReporter), parameters, dynaWaltzParameters, reporter); - return computationManager.execute(execEnv, new DynaWaltzHandler(context)); + return computationManager.execute(execEnv, new DynaWaltzHandler(context, reporter)); } private final class DynaWaltzHandler extends AbstractExecutionHandler { private final DynaWaltzContext context; private final Network dynawoInput; + private final Reporter reporter; - public DynaWaltzHandler(DynaWaltzContext context) { + public DynaWaltzHandler(DynaWaltzContext context, Reporter reporter) { this.context = context; this.dynawoInput = context.getDynaWaltzParameters().isMergeLoads() ? LoadsMerger.mergeLoads(context.getNetwork()) : context.getNetwork(); + this.reporter = reporter; } @Override @@ -173,13 +177,13 @@ public List before(Path workingDir) throws IOException { @Override public DynamicSimulationResult after(Path workingDir, ExecutionReport report) throws IOException { - super.after(workingDir, report); + Path outputsFolder = workingDir.resolve(OUTPUTS_FOLDER); context.getNetwork().getVariantManager().setWorkingVariant(context.getWorkingVariantId()); DynaWaltzParameters parameters = context.getDynaWaltzParameters(); DumpFileParameters dumpFileParameters = parameters.getDumpFileParameters(); boolean status = true; if (parameters.isWriteFinalState()) { - Path outputNetworkFile = workingDir.resolve(OUTPUTS_FOLDER).resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_IIDM_FILENAME); + Path outputNetworkFile = outputsFolder.resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_IIDM_FILENAME); if (Files.exists(outputNetworkFile)) { NetworkResultsUpdater.update(context.getNetwork(), NetworkXml.read(outputNetworkFile), context.getDynaWaltzParameters().isMergeLoads()); } else { @@ -187,24 +191,46 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th } } if (dumpFileParameters.exportDumpFile()) { - Path outputDumpFile = workingDir.resolve(OUTPUTS_FOLDER).resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_DUMP_FILENAME); + Path outputDumpFile = outputsFolder.resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_DUMP_FILENAME); if (Files.exists(outputDumpFile)) { Files.copy(outputDumpFile, dumpFileParameters.dumpFileFolder().resolve(workingDir.getFileName() + "_" + OUTPUT_DUMP_FILENAME), StandardCopyOption.REPLACE_EXISTING); } else { LOGGER.warn("Dump file {} not found, export will be skipped", OUTPUT_DUMP_FILENAME); } } - Path curvesPath = workingDir.resolve(CURVES_OUTPUT_PATH).toAbsolutePath().resolve(CURVES_FILENAME); - Map curves = new HashMap<>(); - if (Files.exists(curvesPath)) { - Map> curvesPerVersion = TimeSeries.parseCsv(curvesPath, new TimeSeriesCsvConfig(TimeSeriesConstants.DEFAULT_SEPARATOR, false, TimeFormat.FRACTIONS_OF_SECOND)); - curvesPerVersion.values().forEach(l -> l.forEach(curve -> curves.put(curve.getMetadata().getName(), curve))); + + //Timeline + Path timelineFile = outputsFolder.resolve(DYNAWO_TIMELINE_FOLDER).resolve(TIMELINE_FILENAME); + if (Files.exists(timelineFile)) { + Reporter timelineReporter = DynawaltzReports.createDynaWaltzTimelineReporter(reporter); + new CsvTimeLineParser().parse(timelineFile).forEach(e -> CommonReports.reportTimelineEvent(timelineReporter, e)); } else { - if (context.withCurves()) { + LOGGER.warn("Timeline file not found"); + } + + //Dynawo log + String logs = null; + Path logFile = outputsFolder.resolve(LOGS_FOLDER).resolve(LOGS_FILENAME); + if (Files.exists(logFile)) { + logs = Files.readString(logFile); + } else { + LOGGER.warn("Dynawo logs file not found"); + } + + //Curves + Map curves = new HashMap<>(); + if (context.withCurves()) { + Path curvesPath = workingDir.resolve(CURVES_OUTPUT_PATH).toAbsolutePath().resolve(CURVES_FILENAME); + if (Files.exists(curvesPath)) { + Map> curvesPerVersion = TimeSeries.parseCsv(curvesPath, new TimeSeriesCsvConfig(TimeSeriesConstants.DEFAULT_SEPARATOR, false, TimeFormat.FRACTIONS_OF_SECOND)); + curvesPerVersion.values().forEach(l -> l.forEach(curve -> curves.put(curve.getMetadata().getName(), curve))); + } else { + LOGGER.warn("Curves folder not found"); status = false; } } - return new DynamicSimulationResultImpl(status, null, curves, DynamicSimulationResult.emptyTimeLine()); + + return new DynamicSimulationResultImpl(status, logs, curves, DynamicSimulationResult.emptyTimeLine()); } private void writeInputFiles(Path workingDir) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynawaltzReports.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynawaltzReports.java index e6aafb366..770bc85f6 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynawaltzReports.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynawaltzReports.java @@ -30,6 +30,11 @@ public static Reporter createDynaWaltzContextReporter(Reporter reporter) { "Dynawaltz models processing"); } + public static Reporter createDynaWaltzTimelineReporter(Reporter reporter) { + return reporter.createSubReporter("dynawaltzTimeline", + "Dynawaltz Timeline"); + } + public static void reportDuplicateStaticId(Reporter reporter, String duplicateId, String modelName, String dynamicId) { reporter.report(Report.builder() .withKey("duplicateId") diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java index dc047fe6a..2d0a0d93b 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java @@ -240,4 +240,28 @@ void testSmib() { assertEquals(1, timeLine.toArray().length); assertNull(timeLine.toArray()[0]); // FIXME } + + @Test + void testSimulationError() { + Network network = Network.read(new ResourceDataSource("powsybl_dynawaltz", new ResourceSet("/error", "powsybl_dynawaltz.xiidm"))); + + GroovyDynamicModelsSupplier dynamicModelsSupplier = new GroovyDynamicModelsSupplier( + getResourceAsStream("/error/models.groovy"), + GroovyExtension.find(DynamicModelGroovyExtension.class, DynaWaltzProvider.NAME)); + + dynaWaltzParameters.setModelsParameters(ParametersXml.load(getResourceAsStream("/error/models.par"))) + .setNetworkParameters(ParametersXml.load(getResourceAsStream("/error/network.par"), "NETWORK")) + .setSolverParameters(ParametersXml.load(getResourceAsStream("/error/solvers.par"), "3")) + .setSolverType(DynaWaltzParameters.SolverType.IDA) + .setDefaultDumpFileParameters(); + + DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, EventModelsSupplier.empty(), CurvesSupplier.empty(), + VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) + .join(); + + assertFalse(result.isOk()); + assertNotNull(result.getLogs()); + assertEquals(1, result.getTimeLine().toArray().length); + assertTrue(result.getCurves().isEmpty()); + } } diff --git a/dynawo-integration-tests/src/test/resources/error/models.groovy b/dynawo-integration-tests/src/test/resources/error/models.groovy new file mode 100644 index 000000000..27efab494 --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/error/models.groovy @@ -0,0 +1,30 @@ +package error + +import com.powsybl.iidm.network.Generator +import com.powsybl.iidm.network.Load + +for (Generator equipment : network.generators) { + if (equipment.energySource.name() == "HYDRO") { + GeneratorSynchronousThreeWindingsGoverNordicVRNordic { + staticId equipment.id + parameterSetId "Nordic" + equipment.id + } + } else if (equipment.energySource.name() == "THERMAL") { + GeneratorSynchronousFourWindingsPmConstVRNordic { + staticId equipment.id + parameterSetId "Nordic" + equipment.id + } + } else if (equipment.energySource.name() == "OTHER") { + GeneratorSynchronousThreeWindingsPmConstVRNordic { + staticId equipment.id + parameterSetId "Nordic" + equipment.id + } + } +} + +for (Load equipment : network.loads) { + LoadAlphaBeta { + staticId equipment.id + parameterSetId "LAB" + } +} diff --git a/dynawo-integration-tests/src/test/resources/error/models.par b/dynawo-integration-tests/src/test/resources/error/models.par new file mode 100644 index 000000000..a786647fa --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/error/models.par @@ -0,0 +1,1013 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dynawo-integration-tests/src/test/resources/error/network.par b/dynawo-integration-tests/src/test/resources/error/network.par new file mode 100644 index 000000000..f34881631 --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/error/network.par @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dynawo-integration-tests/src/test/resources/error/powsybl_dynawaltz.xiidm b/dynawo-integration-tests/src/test/resources/error/powsybl_dynawaltz.xiidm new file mode 100644 index 000000000..4b2b7c1d1 --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/error/powsybl_dynawaltz.xiidm @@ -0,0 +1,2195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dynawo-integration-tests/src/test/resources/error/solvers.par b/dynawo-integration-tests/src/test/resources/error/solvers.par new file mode 100644 index 000000000..71b76a308 --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/error/solvers.par @@ -0,0 +1,10 @@ + + + + + + + + + + From c7df4060932a0434702c5f67202c385197e3ca59 Mon Sep 17 00:00:00 2001 From: lisrte Date: Mon, 13 Nov 2023 16:35:45 +0100 Subject: [PATCH 08/20] Add log parser Signed-off-by: lisrte --- .../dynawo/commons/AbstractCsvParser.java | 80 +++++++++++++++++++ .../powsybl/dynawo/commons/CommonReports.java | 15 ++++ .../commons/dynawologs/CsvLogParser.java | 45 +++++++++++ .../dynawo/commons/dynawologs/LogEntry.java | 17 ++++ .../dynawo/commons/dynawologs/LogUtils.java | 58 ++++++++++++++ .../commons/timeline/CsvTimeLineParser.java | 71 ++++------------ .../commons/dynawologs/CsvLogParserTest.java | 45 +++++++++++ .../timeline/CsvTimeLineParserTest.java | 2 +- commons/src/test/resources/dynawo.log | 12 +++ .../powsybl/dynawaltz/DynaWaltzProvider.java | 3 + 10 files changed, 290 insertions(+), 58 deletions(-) create mode 100644 commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java create mode 100644 commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java create mode 100644 commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogEntry.java create mode 100644 commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java create mode 100644 commons/src/test/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParserTest.java create mode 100644 commons/src/test/resources/dynawo.log diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java b/commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java new file mode 100644 index 000000000..2e60b88e1 --- /dev/null +++ b/commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java @@ -0,0 +1,80 @@ +/** + * 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/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.dynawo.commons; + +import com.powsybl.commons.PowsyblException; +import com.univocity.parsers.common.ParsingContext; +import com.univocity.parsers.common.ResultIterator; +import com.univocity.parsers.csv.CsvParser; +import com.univocity.parsers.csv.CsvParserSettings; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; + +/** + * @author Laurent Issertial {@literal } + */ +public abstract class AbstractCsvParser { + + protected static final char DEFAULT_SEPARATOR = '|'; + + private final char separator; + + public AbstractCsvParser(char separator) { + this.separator = separator; + } + + public List parse(Path file) { + if (!Files.exists(file)) { + return Collections.emptyList(); + } + + try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) { + return parse(reader); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private List parse(BufferedReader reader) { + Objects.requireNonNull(reader); + CsvParserSettings settings = new CsvParserSettings(); + settings.getFormat().setDelimiter(separator); + settings.getFormat().setQuoteEscape('"'); + settings.getFormat().setLineSeparator(System.lineSeparator()); + settings.setMaxColumns(getNbColumns()); + CsvParser csvParser = new CsvParser(settings); + ResultIterator iterator = csvParser.iterate(reader).iterator(); + return read(iterator); + } + + protected List read(ResultIterator iterator) { + List logs = new ArrayList<>(); + int iLine = 0; + while (iterator.hasNext()) { + iLine++; + String[] tokens = iterator.next(); + if (!hasCorrectNbColumns(tokens.length)) { + throw new PowsyblException("Columns of line " + iLine + " are inconsistent"); + } + createEntry(tokens).ifPresent(logs::add); + } + return logs; + } + + protected abstract Optional createEntry(String[] tokens); + + protected abstract boolean hasCorrectNbColumns(int tokensSize); + + protected abstract int getNbColumns(); +} diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/CommonReports.java b/commons/src/main/java/com/powsybl/dynawo/commons/CommonReports.java index 81d5b5206..a5ede19af 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/CommonReports.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/CommonReports.java @@ -10,6 +10,7 @@ import com.powsybl.commons.reporter.Report; import com.powsybl.commons.reporter.Reporter; import com.powsybl.commons.reporter.TypedValue; +import com.powsybl.dynawo.commons.dynawologs.LogEntry; import com.powsybl.dynawo.commons.timeline.TimelineEntry; /** @@ -23,6 +24,11 @@ public final class CommonReports { private CommonReports() { } + public static Reporter createDynawoLogReporter(Reporter reporter) { + return reporter.createSubReporter("dynawoLog", + "Dynawo Log"); + } + public static void reportTimelineEvent(Reporter reporter, TimelineEntry timelineEntry) { reporter.report(Report.builder() .withKey("DynawoTimelineEvent") @@ -33,4 +39,13 @@ public static void reportTimelineEvent(Reporter reporter, TimelineEntry timeline .withSeverity(TypedValue.TRACE_SEVERITY) .build()); } + + public static void reportLogEvent(Reporter reporter, LogEntry logEntry) { + reporter.report(Report.builder() + .withKey("DynawoTimelineEvent") + .withDefaultMessage("${message}") + .withValue("message", logEntry.message()) + .withSeverity(logEntry.severity()) + .build()); + } } diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java new file mode 100644 index 000000000..8ec49fc6f --- /dev/null +++ b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java @@ -0,0 +1,45 @@ +/** + * 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/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.dynawo.commons.dynawologs; + +import com.powsybl.dynawo.commons.AbstractCsvParser; + +import java.util.Optional; + +/** + * @author Laurent Issertial {@literal } + */ +public final class CsvLogParser extends AbstractCsvParser { + + private static final int NB_COLUMNS = 4; + + public CsvLogParser() { + this(DEFAULT_SEPARATOR); + } + + public CsvLogParser(char separator) { + super(separator); + } + + //TODO fix dynawo.log use of | + @Override + protected Optional createEntry(String[] tokens) { + return tokens.length == NB_COLUMNS ? LogUtils.createLog(tokens[1], tokens[2] + " " + tokens[3]) + : LogUtils.createLog(tokens[1], tokens[2]); + } + + @Override + protected boolean hasCorrectNbColumns(int tokensSize) { + return tokensSize == NB_COLUMNS - 1 || tokensSize == NB_COLUMNS; + } + + @Override + protected int getNbColumns() { + return NB_COLUMNS; + } +} diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogEntry.java b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogEntry.java new file mode 100644 index 000000000..928221c4f --- /dev/null +++ b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogEntry.java @@ -0,0 +1,17 @@ +/** + * 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/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.dynawo.commons.dynawologs; + +import com.powsybl.commons.reporter.TypedValue; + +/** + * @author Laurent Issertial {@literal } + */ +public record LogEntry(TypedValue severity, String message) { + +} diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java new file mode 100644 index 000000000..fad9576fd --- /dev/null +++ b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java @@ -0,0 +1,58 @@ +/** + * 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/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.dynawo.commons.dynawologs; + +import com.powsybl.commons.reporter.TypedValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Optional; + +/** + * @author Laurent Issertial {@literal } + */ +public final class LogUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(CsvLogParser.class); + private static final String EMPTY_START = "======"; + private static final String EMPTY_BREAKER = "------"; + + private LogUtils() { + } + + public static Optional createLog(String severity, String message) { + if (severity == null) { + LOGGER.warn("Inconsistent log entry (modelName: '{}', message: '{}')", severity, message); + } else { + if (emptyMessage(message)) { + LOGGER.debug("Empty message, the entry will be skipped : {}", message); + } else { + try { + return Optional.of(new LogEntry(convertDynawoLog(severity), message)); + } catch (IllegalArgumentException e) { + LOGGER.warn("Inconsistent severity entry '{}'", severity); + } + } + } + return Optional.empty(); + } + + private static TypedValue convertDynawoLog(String severity) { + return switch (severity) { + case "DEBUG" -> TypedValue.DEBUG_SEVERITY; + case "INFO" -> TypedValue.INFO_SEVERITY; + case "WARN" -> TypedValue.WARN_SEVERITY; + case "ERROR" -> TypedValue.ERROR_SEVERITY; + default -> throw new IllegalArgumentException(); + }; + } + + private static boolean emptyMessage(String message) { + return message == null || message.startsWith(EMPTY_BREAKER) || message.startsWith(EMPTY_START); + } +} diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParser.java b/commons/src/main/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParser.java index 473fff818..70b3e4a52 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParser.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParser.java @@ -7,80 +7,37 @@ */ package com.powsybl.dynawo.commons.timeline; -import com.powsybl.commons.PowsyblException; -import com.univocity.parsers.common.ParsingContext; -import com.univocity.parsers.common.ResultIterator; -import com.univocity.parsers.csv.CsvParser; -import com.univocity.parsers.csv.CsvParserSettings; +import com.powsybl.dynawo.commons.AbstractCsvParser; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; +import java.util.Optional; /** * @author Laurent Issertial {@literal } */ -public final class CsvTimeLineParser implements TimeLineParser { +public final class CsvTimeLineParser extends AbstractCsvParser implements TimeLineParser { private static final int NB_COLUMNS = 3; - private final char separator; public CsvTimeLineParser() { - this('|'); + this(DEFAULT_SEPARATOR); } public CsvTimeLineParser(char separator) { - this.separator = separator; + super(separator); } - public List parse(Path file) { - return parse(file, separator); + @Override + protected Optional createEntry(String[] tokens) { + return TimeLineUtil.createEvent(tokens[0], tokens[1], tokens[2]); } - public static List parse(Path file, char separator) { - if (!Files.exists(file)) { - return Collections.emptyList(); - } - - try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) { - return parse(reader, separator); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - static List parse(BufferedReader reader, char separator) { - Objects.requireNonNull(reader); - CsvParserSettings settings = new CsvParserSettings(); - settings.getFormat().setDelimiter(separator); - settings.getFormat().setQuoteEscape('"'); - settings.getFormat().setLineSeparator(System.lineSeparator()); - settings.setMaxColumns(NB_COLUMNS); - CsvParser csvParser = new CsvParser(settings); - ResultIterator iterator = csvParser.iterate(reader).iterator(); - return read(iterator); + @Override + protected boolean hasCorrectNbColumns(int tokensSize) { + return NB_COLUMNS == tokensSize; } - static List read(ResultIterator iterator) { - List timeline = new ArrayList<>(); - int iLine = 0; - while (iterator.hasNext()) { - iLine++; - String[] tokens = iterator.next(); - if (tokens.length != NB_COLUMNS) { - throw new PowsyblException("Columns of line " + iLine + " are inconsistent"); - } - TimeLineUtil.createEvent(tokens[0], tokens[1], tokens[2]) - .ifPresent(timeline::add); - } - return timeline; + @Override + protected int getNbColumns() { + return NB_COLUMNS; } - } diff --git a/commons/src/test/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParserTest.java b/commons/src/test/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParserTest.java new file mode 100644 index 000000000..f9fc16b28 --- /dev/null +++ b/commons/src/test/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParserTest.java @@ -0,0 +1,45 @@ +/** + * 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/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.dynawo.commons.dynawologs; + +import com.powsybl.commons.reporter.TypedValue; +import org.junit.jupiter.api.Test; + +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.List; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Laurent Issertial {@literal } + */ +class CsvLogParserTest { + + @Test + void testLog() throws URISyntaxException { + + Path path = Path.of(Objects.requireNonNull(getClass().getResource("/dynawo.log")).toURI()); + List logs = new CsvLogParser().parse(path); + + assertEquals(6, logs.size()); + assertEquals("DYNAWO VERSION : 1.4.1", logs.get(0).message()); + assertEquals(TypedValue.INFO_SEVERITY, logs.get(0).severity()); + assertEquals("time iter num order (k) time step (h)", logs.get(1).message()); + assertEquals(TypedValue.INFO_SEVERITY, logs.get(1).severity()); + assertEquals("0.000 0 0 0.010", logs.get(2).message()); + assertEquals(TypedValue.INFO_SEVERITY, logs.get(2).severity()); + assertEquals("call of SolverReInit i.e. a new symbolic and numerical factorization will be performed", logs.get(3).message()); + assertEquals(TypedValue.DEBUG_SEVERITY, logs.get(3).severity()); + assertEquals("five consecutive steps have been taken that satisfy a scaled step length test", logs.get(4).message()); + assertEquals(TypedValue.WARN_SEVERITY, logs.get(4).severity()); + assertEquals("KINSOL fails to solve the problem ( DYNSolverKINAlgRestoration.cpp:394 )", logs.get(5).message()); + assertEquals(TypedValue.ERROR_SEVERITY, logs.get(5).severity()); + } +} diff --git a/commons/src/test/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParserTest.java b/commons/src/test/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParserTest.java index 91df30869..ad620f01e 100644 --- a/commons/src/test/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParserTest.java +++ b/commons/src/test/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParserTest.java @@ -51,7 +51,7 @@ void testTimeline(String fileName) throws URISyntaxException { @Test void testInconsistentFile() throws URISyntaxException { Path path = Path.of(Objects.requireNonNull(getClass().getResource("/wrongTimeline.log")).toURI()); - Exception e = assertThrows(PowsyblException.class, () -> CsvTimeLineParser.parse(path, '|')); + Exception e = assertThrows(PowsyblException.class, () -> new CsvTimeLineParser('|').parse(path)); assertEquals("Columns of line 2 are inconsistent", e.getMessage()); } } diff --git a/commons/src/test/resources/dynawo.log b/commons/src/test/resources/dynawo.log new file mode 100644 index 000000000..c6e2e7c0b --- /dev/null +++ b/commons/src/test/resources/dynawo.log @@ -0,0 +1,12 @@ +2023-11-09 11:36:53 | INFO | ============================================================ +2023-11-09 11:36:53 | INFO | DYNAWO VERSION : 1.4.1 +2023-11-09 11:36:53 | INFO | ============================================================ +2023-11-09 11:36:53 | INFO | +2023-11-13 11:36:53 | INFO | time | iter num order (k) time step (h) +2023-11-13 11:36:53 | INFO | ----------------------------------------------------------------------- +2023-11-13 11:36:53 | INFO | 0.000 | 0 0 0.010 +2023-11-09 11:36:58 | TRACE | Algebraic mode change for model CONST.TG6 at t = 0 +2023-11-09 11:36:58 | | Algebraic mode change for model CONST.TG7 at t = 0 +2023-11-09 11:36:58 | DEBUG | call of SolverReInit i.e. a new symbolic and numerical factorization will be performed +2023-11-09 11:36:59 | WARN | five consecutive steps have been taken that satisfy a scaled step length test +2023-11-09 11:36:59 | ERROR | KINSOL fails to solve the problem ( DYNSolverKINAlgRestoration.cpp:394 ) diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index 12cb6c0ba..a2955be91 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -18,6 +18,7 @@ import com.powsybl.dynawaltz.xml.JobsXml; import com.powsybl.dynawaltz.xml.ParametersXml; import com.powsybl.dynawo.commons.*; +import com.powsybl.dynawo.commons.dynawologs.CsvLogParser; import com.powsybl.dynawo.commons.loadmerge.LoadsMerger; import com.powsybl.dynawo.commons.timeline.CsvTimeLineParser; import com.powsybl.iidm.network.Network; @@ -213,6 +214,8 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th Path logFile = outputsFolder.resolve(LOGS_FOLDER).resolve(LOGS_FILENAME); if (Files.exists(logFile)) { logs = Files.readString(logFile); + Reporter logReporter = CommonReports.createDynawoLogReporter(reporter); + new CsvLogParser().parse(logFile).forEach(e -> CommonReports.reportLogEvent(logReporter, e)); } else { LOGGER.warn("Dynawo logs file not found"); } From 8c646528ae253c80e658e58ddd7501a0854db0a7 Mon Sep 17 00:00:00 2001 From: lisrte Date: Thu, 16 Nov 2023 10:43:46 +0100 Subject: [PATCH 09/20] Check error in dyn_fs_0.err Signed-off-by: lisrte --- .../powsybl/dynawaltz/DynaWaltzProvider.java | 102 +++++++++++------- .../com/powsybl/dynawo/it/DynaWaltzTest.java | 24 +++-- 2 files changed, 82 insertions(+), 44 deletions(-) diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index a2955be91..a6baa67fb 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -38,6 +38,8 @@ import java.nio.file.StandardCopyOption; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import static com.powsybl.dynawaltz.xml.DynaWaltzConstants.*; @@ -59,6 +61,9 @@ public class DynaWaltzProvider implements DynamicSimulationProvider { private static final String OUTPUT_DUMP_FILENAME = "outputState.dmp"; private static final String TIMELINE_FILENAME = "timeline.log"; private static final String LOGS_FILENAME = "dynawaltz.log"; + private static final String ERROR_FILENAME = "dyn_fs_0.err"; + private static final String DYNAWO_ERROR_PATTERN = "DYN Error: "; + private static final Logger LOGGER = LoggerFactory.getLogger(DynaWaltzProvider.class); @@ -182,58 +187,81 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th context.getNetwork().getVariantManager().setWorkingVariant(context.getWorkingVariantId()); DynaWaltzParameters parameters = context.getDynaWaltzParameters(); DumpFileParameters dumpFileParameters = parameters.getDumpFileParameters(); - boolean status = true; - if (parameters.isWriteFinalState()) { - Path outputNetworkFile = outputsFolder.resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_IIDM_FILENAME); - if (Files.exists(outputNetworkFile)) { - NetworkResultsUpdater.update(context.getNetwork(), NetworkXml.read(outputNetworkFile), context.getDynaWaltzParameters().isMergeLoads()); - } else { - status = false; - } - } - if (dumpFileParameters.exportDumpFile()) { - Path outputDumpFile = outputsFolder.resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_DUMP_FILENAME); - if (Files.exists(outputDumpFile)) { - Files.copy(outputDumpFile, dumpFileParameters.dumpFileFolder().resolve(workingDir.getFileName() + "_" + OUTPUT_DUMP_FILENAME), StandardCopyOption.REPLACE_EXISTING); - } else { - LOGGER.warn("Dump file {} not found, export will be skipped", OUTPUT_DUMP_FILENAME); - } - } - //Timeline - Path timelineFile = outputsFolder.resolve(DYNAWO_TIMELINE_FOLDER).resolve(TIMELINE_FILENAME); - if (Files.exists(timelineFile)) { - Reporter timelineReporter = DynawaltzReports.createDynaWaltzTimelineReporter(reporter); - new CsvTimeLineParser().parse(timelineFile).forEach(e -> CommonReports.reportTimelineEvent(timelineReporter, e)); - } else { - LOGGER.warn("Timeline file not found"); - } + DynamicSimulationResult.Status status = DynamicSimulationResult.Status.SUCCEED; + String error = ""; + Map curves = new HashMap<>(); //Dynawo log - String logs = null; Path logFile = outputsFolder.resolve(LOGS_FOLDER).resolve(LOGS_FILENAME); if (Files.exists(logFile)) { - logs = Files.readString(logFile); Reporter logReporter = CommonReports.createDynawoLogReporter(reporter); new CsvLogParser().parse(logFile).forEach(e -> CommonReports.reportLogEvent(logReporter, e)); } else { LOGGER.warn("Dynawo logs file not found"); } - //Curves - Map curves = new HashMap<>(); - if (context.withCurves()) { - Path curvesPath = workingDir.resolve(CURVES_OUTPUT_PATH).toAbsolutePath().resolve(CURVES_FILENAME); - if (Files.exists(curvesPath)) { - Map> curvesPerVersion = TimeSeries.parseCsv(curvesPath, new TimeSeriesCsvConfig(TimeSeriesConstants.DEFAULT_SEPARATOR, false, TimeFormat.FRACTIONS_OF_SECOND)); - curvesPerVersion.values().forEach(l -> l.forEach(curve -> curves.put(curve.getMetadata().getName(), curve))); + // Error file + Path errorFile = workingDir.resolve(ERROR_FILENAME); + if(Files.exists(errorFile)) { + Matcher errorMatcher = Pattern.compile(DYNAWO_ERROR_PATTERN + "(.*)") + .matcher(Files.readString(errorFile)); + if (!errorMatcher.find()) { + + //Update network + if (parameters.isWriteFinalState()) { + Path outputNetworkFile = outputsFolder.resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_IIDM_FILENAME); + if (Files.exists(outputNetworkFile)) { + NetworkResultsUpdater.update(context.getNetwork(), NetworkXml.read(outputNetworkFile), context.getDynaWaltzParameters().isMergeLoads()); + } else { + LOGGER.warn("Output IIDM file not found"); + status = DynamicSimulationResult.Status.FAILED; + error = "Dynawo Output IIDM file not found"; + } + } + + //Dump file + if (dumpFileParameters.exportDumpFile()) { + Path outputDumpFile = outputsFolder.resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_DUMP_FILENAME); + if (Files.exists(outputDumpFile)) { + Files.copy(outputDumpFile, dumpFileParameters.dumpFileFolder().resolve(workingDir.getFileName() + "_" + OUTPUT_DUMP_FILENAME), StandardCopyOption.REPLACE_EXISTING); + } else { + LOGGER.warn("Dump file {} not found, export will be skipped", OUTPUT_DUMP_FILENAME); + } + } + + //Timeline + Path timelineFile = outputsFolder.resolve(DYNAWO_TIMELINE_FOLDER).resolve(TIMELINE_FILENAME); + if (Files.exists(timelineFile)) { + Reporter timelineReporter = DynawaltzReports.createDynaWaltzTimelineReporter(reporter); + new CsvTimeLineParser().parse(timelineFile).forEach(e -> CommonReports.reportTimelineEvent(timelineReporter, e)); + } else { + LOGGER.warn("Timeline file not found"); + } + + //Curves + if (context.withCurves()) { + Path curvesPath = workingDir.resolve(CURVES_OUTPUT_PATH).toAbsolutePath().resolve(CURVES_FILENAME); + if (Files.exists(curvesPath)) { + Map> curvesPerVersion = TimeSeries.parseCsv(curvesPath, new TimeSeriesCsvConfig(TimeSeriesConstants.DEFAULT_SEPARATOR, false, TimeFormat.FRACTIONS_OF_SECOND)); + curvesPerVersion.values().forEach(l -> l.forEach(curve -> curves.put(curve.getMetadata().getName(), curve))); + } else { + LOGGER.warn("Curves folder not found"); + status = DynamicSimulationResult.Status.FAILED; + error = "Dynawo curves folder not found"; + } + } } else { - LOGGER.warn("Curves folder not found"); - status = false; + status = DynamicSimulationResult.Status.FAILED; + error = errorMatcher.group().substring(DYNAWO_ERROR_PATTERN.length()); } + } else { + LOGGER.warn("Error file not found"); + status = DynamicSimulationResult.Status.FAILED; + error = "Dynawo error log file not found"; } - return new DynamicSimulationResultImpl(status, logs, curves, DynamicSimulationResult.emptyTimeLine()); + return new DynamicSimulationResultImpl(status, error, curves, DynamicSimulationResult.emptyTimeLine()); } private void writeInputFiles(Path workingDir) { diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java index 2d0a0d93b..aaa786279 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java @@ -50,7 +50,7 @@ void setUp() throws Exception { super.setUp(); provider = new DynaWaltzProvider(new DynaWaltzConfig(Path.of("/dynawo"), false)); parameters = new DynamicSimulationParameters() - .setStartTime(1) + .setStartTime(0) .setStopTime(100); dynaWaltzParameters = new DynaWaltzParameters(); parameters.addExtension(DynaWaltzParameters.class, dynaWaltzParameters); @@ -85,7 +85,9 @@ void testIeee14() { VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); + assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); assertTrue(result.isOk()); + assertTrue(result.getError().isEmpty()); assertEquals(41, result.getCurves().size()); DoubleTimeSeries ts1 = (DoubleTimeSeries) result.getCurve("_GEN____1_SM_generator_UStatorPu"); assertEquals("_GEN____1_SM_generator_UStatorPu", ts1.getMetadata().getName()); @@ -144,8 +146,9 @@ void testIeee14WithDump() throws IOException { VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); + assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); assertTrue(result.isOk()); - + assertTrue(result.getError().isEmpty()); } @Test @@ -169,8 +172,10 @@ void testSvc() { VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); + assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); assertTrue(result.isOk()); - assertEquals(0, result.getCurves().size()); + assertTrue(result.getError().isEmpty()); + assertTrue(result.getCurves().isEmpty()); StringTimeSeries timeLine = result.getTimeLine(); assertEquals(1, timeLine.toArray().length); assertNull(timeLine.toArray()[0]); // FIXME @@ -197,8 +202,10 @@ void testHvdc() { VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); + assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); assertTrue(result.isOk()); - assertEquals(0, result.getCurves().size()); + assertTrue(result.getError().isEmpty()); + assertTrue(result.getCurves().isEmpty()); StringTimeSeries timeLine = result.getTimeLine(); assertEquals(1, timeLine.toArray().length); assertNull(timeLine.toArray()[0]); // FIXME @@ -234,7 +241,9 @@ void testSmib() { VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); + assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); assertTrue(result.isOk()); + assertTrue(result.getError().isEmpty()); assertEquals(35, result.getCurves().size()); StringTimeSeries timeLine = result.getTimeLine(); assertEquals(1, timeLine.toArray().length); @@ -252,16 +261,17 @@ void testSimulationError() { dynaWaltzParameters.setModelsParameters(ParametersXml.load(getResourceAsStream("/error/models.par"))) .setNetworkParameters(ParametersXml.load(getResourceAsStream("/error/network.par"), "NETWORK")) .setSolverParameters(ParametersXml.load(getResourceAsStream("/error/solvers.par"), "3")) - .setSolverType(DynaWaltzParameters.SolverType.IDA) + .setSolverType(DynaWaltzParameters.SolverType.SIM) .setDefaultDumpFileParameters(); DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, EventModelsSupplier.empty(), CurvesSupplier.empty(), VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); + assertEquals(DynamicSimulationResult.Status.FAILED, result.getStatus()); assertFalse(result.isOk()); - assertNotNull(result.getLogs()); - assertEquals(1, result.getTimeLine().toArray().length); + assertEquals("time step <= 0.1 s for more than 10 iterations ( DYNSolverCommonFixedTimeStep.cpp:419 )", result.getError()); + assertEquals(DynamicSimulationResult.emptyTimeLine(), result.getTimeLine()); assertTrue(result.getCurves().isEmpty()); } } From 0afb06056ea43da48a1a83230683e48f91442b21 Mon Sep 17 00:00:00 2001 From: lisrte Date: Thu, 16 Nov 2023 13:55:11 +0100 Subject: [PATCH 10/20] Fix integration test Signed-off-by: lisrte --- .../com/powsybl/dynawaltz/DynaWaltzProvider.java | 4 ++-- .../java/com/powsybl/dynawo/it/DynaWaltzTest.java | 9 +++++++-- .../src/test/resources/error/eventModels.groovy | 13 +++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 dynawo-integration-tests/src/test/resources/error/eventModels.groovy diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index a6baa67fb..0234e317e 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -18,6 +18,7 @@ import com.powsybl.dynawaltz.xml.JobsXml; import com.powsybl.dynawaltz.xml.ParametersXml; import com.powsybl.dynawo.commons.*; +import com.powsybl.dynawo.commons.PowsyblDynawoVersion; import com.powsybl.dynawo.commons.dynawologs.CsvLogParser; import com.powsybl.dynawo.commons.loadmerge.LoadsMerger; import com.powsybl.dynawo.commons.timeline.CsvTimeLineParser; @@ -64,7 +65,6 @@ public class DynaWaltzProvider implements DynamicSimulationProvider { private static final String ERROR_FILENAME = "dyn_fs_0.err"; private static final String DYNAWO_ERROR_PATTERN = "DYN Error: "; - private static final Logger LOGGER = LoggerFactory.getLogger(DynaWaltzProvider.class); private final DynaWaltzConfig dynaWaltzConfig; @@ -203,7 +203,7 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th // Error file Path errorFile = workingDir.resolve(ERROR_FILENAME); - if(Files.exists(errorFile)) { + if (Files.exists(errorFile)) { Matcher errorMatcher = Pattern.compile(DYNAWO_ERROR_PATTERN + "(.*)") .matcher(Files.readString(errorFile)); if (!errorMatcher.find()) { diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java index aaa786279..e1c148b7d 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java @@ -50,7 +50,7 @@ void setUp() throws Exception { super.setUp(); provider = new DynaWaltzProvider(new DynaWaltzConfig(Path.of("/dynawo"), false)); parameters = new DynamicSimulationParameters() - .setStartTime(0) + .setStartTime(1) .setStopTime(100); dynaWaltzParameters = new DynaWaltzParameters(); parameters.addExtension(DynaWaltzParameters.class, dynaWaltzParameters); @@ -258,13 +258,18 @@ void testSimulationError() { getResourceAsStream("/error/models.groovy"), GroovyExtension.find(DynamicModelGroovyExtension.class, DynaWaltzProvider.NAME)); + GroovyEventModelsSupplier eventModelsSupplier = new GroovyEventModelsSupplier( + getResourceAsStream("/error/eventModels.groovy"), + GroovyExtension.find(EventModelGroovyExtension.class, DynaWaltzProvider.NAME)); + + parameters.setStopTime(200); dynaWaltzParameters.setModelsParameters(ParametersXml.load(getResourceAsStream("/error/models.par"))) .setNetworkParameters(ParametersXml.load(getResourceAsStream("/error/network.par"), "NETWORK")) .setSolverParameters(ParametersXml.load(getResourceAsStream("/error/solvers.par"), "3")) .setSolverType(DynaWaltzParameters.SolverType.SIM) .setDefaultDumpFileParameters(); - DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, EventModelsSupplier.empty(), CurvesSupplier.empty(), + DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, CurvesSupplier.empty(), VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); diff --git a/dynawo-integration-tests/src/test/resources/error/eventModels.groovy b/dynawo-integration-tests/src/test/resources/error/eventModels.groovy new file mode 100644 index 000000000..97e19c954 --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/error/eventModels.groovy @@ -0,0 +1,13 @@ +package error + +Disconnect { + staticId "L4032-4044" + startTime 1.1 +} +NodeFault { + staticId "4032_401" + startTime 1 + faultTime 0.1 + rPu 0.025 + xPu 0.025 +} From aa41a4efe503a2057c58673680616a10c6cdfc5b Mon Sep 17 00:00:00 2001 From: lisrte Date: Wed, 22 Nov 2023 10:38:10 +0100 Subject: [PATCH 11/20] Use TimelineEvent instead of StringTimeSeries Signed-off-by: lisrte --- .../powsybl/dynawaltz/DynaWaltzProvider.java | 18 ++++--- .../com/powsybl/dynawo/it/DynaWaltzTest.java | 53 +++++++++---------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index 0234e317e..c0f75607a 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -189,7 +189,8 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th DumpFileParameters dumpFileParameters = parameters.getDumpFileParameters(); DynamicSimulationResult.Status status = DynamicSimulationResult.Status.SUCCEED; - String error = ""; + String statusText = ""; + List timeline = new ArrayList<>(); Map curves = new HashMap<>(); //Dynawo log @@ -216,7 +217,7 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th } else { LOGGER.warn("Output IIDM file not found"); status = DynamicSimulationResult.Status.FAILED; - error = "Dynawo Output IIDM file not found"; + statusText = "Dynawo Output IIDM file not found"; } } @@ -234,7 +235,10 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th Path timelineFile = outputsFolder.resolve(DYNAWO_TIMELINE_FOLDER).resolve(TIMELINE_FILENAME); if (Files.exists(timelineFile)) { Reporter timelineReporter = DynawaltzReports.createDynaWaltzTimelineReporter(reporter); - new CsvTimeLineParser().parse(timelineFile).forEach(e -> CommonReports.reportTimelineEvent(timelineReporter, e)); + new CsvTimeLineParser().parse(timelineFile).forEach(e -> { + CommonReports.reportTimelineEvent(timelineReporter, e); + timeline.add(new TimelineEvent(e.time(), e.modelName(), e.message())); + }); } else { LOGGER.warn("Timeline file not found"); } @@ -248,20 +252,20 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th } else { LOGGER.warn("Curves folder not found"); status = DynamicSimulationResult.Status.FAILED; - error = "Dynawo curves folder not found"; + statusText = "Dynawo curves folder not found"; } } } else { status = DynamicSimulationResult.Status.FAILED; - error = errorMatcher.group().substring(DYNAWO_ERROR_PATTERN.length()); + statusText = errorMatcher.group().substring(DYNAWO_ERROR_PATTERN.length()); } } else { LOGGER.warn("Error file not found"); status = DynamicSimulationResult.Status.FAILED; - error = "Dynawo error log file not found"; + statusText = "Dynawo error log file not found"; } - return new DynamicSimulationResultImpl(status, error, curves, DynamicSimulationResult.emptyTimeLine()); + return new DynamicSimulationResultImpl(status, statusText, curves, timeline); } private void writeInputFiles(Path workingDir) { diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java index e1c148b7d..00f9d9df9 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java @@ -20,7 +20,6 @@ import com.powsybl.iidm.network.VariantManagerConstants; import com.powsybl.iidm.network.test.SvcTestCaseFactory; import com.powsybl.timeseries.DoubleTimeSeries; -import com.powsybl.timeseries.StringTimeSeries; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -50,7 +49,7 @@ void setUp() throws Exception { super.setUp(); provider = new DynaWaltzProvider(new DynaWaltzConfig(Path.of("/dynawo"), false)); parameters = new DynamicSimulationParameters() - .setStartTime(1) + .setStartTime(0) .setStopTime(100); dynaWaltzParameters = new DynaWaltzParameters(); parameters.addExtension(DynaWaltzParameters.class, dynaWaltzParameters); @@ -86,15 +85,14 @@ void testIeee14() { .join(); assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); - assertTrue(result.isOk()); - assertTrue(result.getError().isEmpty()); + assertTrue(result.getStatusText().isEmpty()); assertEquals(41, result.getCurves().size()); DoubleTimeSeries ts1 = (DoubleTimeSeries) result.getCurve("_GEN____1_SM_generator_UStatorPu"); assertEquals("_GEN____1_SM_generator_UStatorPu", ts1.getMetadata().getName()); assertEquals(587, ts1.toArray().length); - StringTimeSeries timeLine = result.getTimeLine(); - assertEquals(1, timeLine.toArray().length); - assertNull(timeLine.toArray()[0]); // FIXME + List timeLine = result.getTimeLine(); + assertEquals(23, timeLine.size()); + checkFirstTimeLineEvent(timeLine.get(0), 0,"_GEN____8_SM", "PMIN : activation"); } @Test @@ -130,7 +128,7 @@ void testIeee14WithDump() throws IOException { DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); - assertTrue(result.isOk()); + assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); //Use exported dump as input parameters.setStartTime(30); @@ -147,8 +145,6 @@ void testIeee14WithDump() throws IOException { .join(); assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); - assertTrue(result.isOk()); - assertTrue(result.getError().isEmpty()); } @Test @@ -173,12 +169,11 @@ void testSvc() { .join(); assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); - assertTrue(result.isOk()); - assertTrue(result.getError().isEmpty()); + assertTrue(result.getStatusText().isEmpty()); assertTrue(result.getCurves().isEmpty()); - StringTimeSeries timeLine = result.getTimeLine(); - assertEquals(1, timeLine.toArray().length); - assertNull(timeLine.toArray()[0]); // FIXME + List timeLine = result.getTimeLine(); + assertEquals(1, timeLine.size()); + checkFirstTimeLineEvent(timeLine.get(0), 0, "G1", "PMIN : activation"); } @Test @@ -203,12 +198,11 @@ void testHvdc() { .join(); assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); - assertTrue(result.isOk()); - assertTrue(result.getError().isEmpty()); + assertTrue(result.getStatusText().isEmpty()); assertTrue(result.getCurves().isEmpty()); - StringTimeSeries timeLine = result.getTimeLine(); - assertEquals(1, timeLine.toArray().length); - assertNull(timeLine.toArray()[0]); // FIXME + List timeLine = result.getTimeLine(); + assertEquals(7, timeLine.size()); + checkFirstTimeLineEvent(timeLine.get(0), 30.0, "_BUS____5-BUS____6-1_PS", "Tap +1"); } @Test @@ -242,12 +236,10 @@ void testSmib() { .join(); assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); - assertTrue(result.isOk()); - assertTrue(result.getError().isEmpty()); + assertTrue(result.getStatusText().isEmpty()); assertEquals(35, result.getCurves().size()); - StringTimeSeries timeLine = result.getTimeLine(); - assertEquals(1, timeLine.toArray().length); - assertNull(timeLine.toArray()[0]); // FIXME + List timeLine = result.getTimeLine(); + assertTrue(timeLine.isEmpty()); } @Test @@ -274,9 +266,14 @@ void testSimulationError() { .join(); assertEquals(DynamicSimulationResult.Status.FAILED, result.getStatus()); - assertFalse(result.isOk()); - assertEquals("time step <= 0.1 s for more than 10 iterations ( DYNSolverCommonFixedTimeStep.cpp:419 )", result.getError()); - assertEquals(DynamicSimulationResult.emptyTimeLine(), result.getTimeLine()); + assertEquals("time step <= 0.1 s for more than 10 iterations ( DYNSolverCommonFixedTimeStep.cpp:419 )", result.getStatusText()); + assertTrue(result.getTimeLine().isEmpty()); assertTrue(result.getCurves().isEmpty()); } + + private void checkFirstTimeLineEvent(TimelineEvent event, double time, String modelName, String message) { + assertEquals(time, event.time()); + assertEquals(modelName, event.modelName()); + assertEquals(message, event.message()); + } } From 9993a821c34a405fe456f34da951855a7085fd6a Mon Sep 17 00:00:00 2001 From: lisrte Date: Wed, 22 Nov 2023 11:07:55 +0100 Subject: [PATCH 12/20] Fix checkstyle Signed-off-by: lisrte --- .../src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java index 00f9d9df9..87dbd583d 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java @@ -92,7 +92,7 @@ void testIeee14() { assertEquals(587, ts1.toArray().length); List timeLine = result.getTimeLine(); assertEquals(23, timeLine.size()); - checkFirstTimeLineEvent(timeLine.get(0), 0,"_GEN____8_SM", "PMIN : activation"); + checkFirstTimeLineEvent(timeLine.get(0), 0, "_GEN____8_SM", "PMIN : activation"); } @Test From 9c89dd595cb0d4feb39f293012be06b366d0ff45 Mon Sep 17 00:00:00 2001 From: lisrte Date: Mon, 27 Nov 2023 14:05:33 +0100 Subject: [PATCH 13/20] Fix branch update Signed-off-by: lisrte --- .../src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java | 2 +- .../src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index 1a1106682..4e1f98176 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -210,7 +210,7 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th if (parameters.isWriteFinalState()) { Path outputNetworkFile = outputsFolder.resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_IIDM_FILENAME); if (Files.exists(outputNetworkFile)) { - NetworkResultsUpdater.update(context.getNetwork(), NetworkXml.read(outputNetworkFile), context.getDynaWaltzParameters().isMergeLoads()); + NetworkResultsUpdater.update(context.getNetwork(), NetworkSerDe.read(outputNetworkFile), context.getDynaWaltzParameters().isMergeLoads()); } else { LOGGER.warn("Output IIDM file not found"); status = DynamicSimulationResult.Status.FAILED; diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java index 722daa80a..87dbd583d 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java @@ -8,7 +8,6 @@ import com.powsybl.commons.datasource.ResourceDataSource; import com.powsybl.commons.datasource.ResourceSet; -import com.powsybl.commons.reporter.Reporter; import com.powsybl.dynamicsimulation.*; import com.powsybl.dynamicsimulation.groovy.*; import com.powsybl.dynawaltz.DumpFileParameters; From dd8948ce6549e1c46055d1fadc0d627cee44b587 Mon Sep 17 00:00:00 2001 From: lisrte Date: Mon, 27 Nov 2023 14:15:46 +0100 Subject: [PATCH 14/20] Config maven.yml Signed-off-by: lisrte --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index e27a05402..4a31ffaf9 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v1 with: repository: powsybl/powsybl-core - ref: refs/heads/dynamic_simulation_reporter + ref: refs/heads/dynamic_simulation_results - name: Checkout sources uses: actions/checkout@v1 From 431df1517c920e448953133d44e643d8871f4859 Mon Sep 17 00:00:00 2001 From: lisrte Date: Mon, 27 Nov 2023 15:30:57 +0100 Subject: [PATCH 15/20] Fix code smells Signed-off-by: lisrte --- .../dynawo/commons/AbstractCsvParser.java | 2 +- .../commons/dynawologs/CsvLogParser.java | 1 - .../dynawo/commons/dynawologs/LogUtils.java | 2 +- .../timeline/CsvTimeLineParserTest.java | 3 +- .../powsybl/dynawaltz/DynaWaltzProvider.java | 121 ++++++++++-------- 5 files changed, 70 insertions(+), 59 deletions(-) diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java b/commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java index 2e60b88e1..2ccfed9eb 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/AbstractCsvParser.java @@ -30,7 +30,7 @@ public abstract class AbstractCsvParser { private final char separator; - public AbstractCsvParser(char separator) { + protected AbstractCsvParser(char separator) { this.separator = separator; } diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java index 8ec49fc6f..43a429139 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/CsvLogParser.java @@ -26,7 +26,6 @@ public CsvLogParser(char separator) { super(separator); } - //TODO fix dynawo.log use of | @Override protected Optional createEntry(String[] tokens) { return tokens.length == NB_COLUMNS ? LogUtils.createLog(tokens[1], tokens[2] + " " + tokens[3]) diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java index fad9576fd..d1ce67692 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java @@ -18,7 +18,7 @@ */ public final class LogUtils { - private static final Logger LOGGER = LoggerFactory.getLogger(CsvLogParser.class); + private static final Logger LOGGER = LoggerFactory.getLogger(LogUtils.class); private static final String EMPTY_START = "======"; private static final String EMPTY_BREAKER = "------"; diff --git a/commons/src/test/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParserTest.java b/commons/src/test/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParserTest.java index ad620f01e..2b82a1d6a 100644 --- a/commons/src/test/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParserTest.java +++ b/commons/src/test/java/com/powsybl/dynawo/commons/timeline/CsvTimeLineParserTest.java @@ -50,8 +50,9 @@ void testTimeline(String fileName) throws URISyntaxException { @Test void testInconsistentFile() throws URISyntaxException { + CsvTimeLineParser parser = new CsvTimeLineParser('|'); Path path = Path.of(Objects.requireNonNull(getClass().getResource("/wrongTimeline.log")).toURI()); - Exception e = assertThrows(PowsyblException.class, () -> new CsvTimeLineParser('|').parse(path)); + Exception e = assertThrows(PowsyblException.class, () -> parser.parse(path)); assertEquals("Columns of line 2 are inconsistent", e.getMessage()); } } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index 4e1f98176..1708cab6f 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -155,6 +155,11 @@ private final class DynaWaltzHandler extends AbstractExecutionHandler timeline = new ArrayList<>(); + private final Map curves = new HashMap<>(); + private DynamicSimulationResult.Status status = DynamicSimulationResult.Status.SUCCEED; + private String statusText = ""; + public DynaWaltzHandler(DynaWaltzContext context, Reporter reporter) { this.context = context; this.dynawoInput = context.getDynaWaltzParameters().isMergeLoads() @@ -180,77 +185,28 @@ public List before(Path workingDir) throws IOException { @Override public DynamicSimulationResult after(Path workingDir, ExecutionReport report) throws IOException { + Path outputsFolder = workingDir.resolve(OUTPUTS_FOLDER); context.getNetwork().getVariantManager().setWorkingVariant(context.getWorkingVariantId()); DynaWaltzParameters parameters = context.getDynaWaltzParameters(); DumpFileParameters dumpFileParameters = parameters.getDumpFileParameters(); - DynamicSimulationResult.Status status = DynamicSimulationResult.Status.SUCCEED; - String statusText = ""; - List timeline = new ArrayList<>(); - Map curves = new HashMap<>(); - - //Dynawo log - Path logFile = outputsFolder.resolve(LOGS_FOLDER).resolve(LOGS_FILENAME); - if (Files.exists(logFile)) { - Reporter logReporter = CommonReports.createDynawoLogReporter(reporter); - new CsvLogParser().parse(logFile).forEach(e -> CommonReports.reportLogEvent(logReporter, e)); - } else { - LOGGER.warn("Dynawo logs file not found"); - } - + setDynawoLog(outputsFolder); // Error file Path errorFile = workingDir.resolve(ERROR_FILENAME); if (Files.exists(errorFile)) { Matcher errorMatcher = Pattern.compile(DYNAWO_ERROR_PATTERN + "(.*)") .matcher(Files.readString(errorFile)); if (!errorMatcher.find()) { - - //Update network if (parameters.isWriteFinalState()) { - Path outputNetworkFile = outputsFolder.resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_IIDM_FILENAME); - if (Files.exists(outputNetworkFile)) { - NetworkResultsUpdater.update(context.getNetwork(), NetworkSerDe.read(outputNetworkFile), context.getDynaWaltzParameters().isMergeLoads()); - } else { - LOGGER.warn("Output IIDM file not found"); - status = DynamicSimulationResult.Status.FAILED; - statusText = "Dynawo Output IIDM file not found"; - } + updateNetwork(outputsFolder); } - - //Dump file if (dumpFileParameters.exportDumpFile()) { - Path outputDumpFile = outputsFolder.resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_DUMP_FILENAME); - if (Files.exists(outputDumpFile)) { - Files.copy(outputDumpFile, dumpFileParameters.dumpFileFolder().resolve(workingDir.getFileName() + "_" + OUTPUT_DUMP_FILENAME), StandardCopyOption.REPLACE_EXISTING); - } else { - LOGGER.warn("Dump file {} not found, export will be skipped", OUTPUT_DUMP_FILENAME); - } - } - - //Timeline - Path timelineFile = outputsFolder.resolve(DYNAWO_TIMELINE_FOLDER).resolve(TIMELINE_FILENAME); - if (Files.exists(timelineFile)) { - Reporter timelineReporter = DynawaltzReports.createDynaWaltzTimelineReporter(reporter); - new CsvTimeLineParser().parse(timelineFile).forEach(e -> { - CommonReports.reportTimelineEvent(timelineReporter, e); - timeline.add(new TimelineEvent(e.time(), e.modelName(), e.message())); - }); - } else { - LOGGER.warn("Timeline file not found"); + setDumpFile(outputsFolder, dumpFileParameters.dumpFileFolder(), workingDir.getFileName()); } - - //Curves + setTimeline(outputsFolder); if (context.withCurves()) { - Path curvesPath = workingDir.resolve(CURVES_OUTPUT_PATH).toAbsolutePath().resolve(CURVES_FILENAME); - if (Files.exists(curvesPath)) { - Map> curvesPerVersion = TimeSeries.parseCsv(curvesPath, new TimeSeriesCsvConfig(TimeSeriesConstants.DEFAULT_SEPARATOR, false, TimeFormat.FRACTIONS_OF_SECOND)); - curvesPerVersion.values().forEach(l -> l.forEach(curve -> curves.put(curve.getMetadata().getName(), curve))); - } else { - LOGGER.warn("Curves folder not found"); - status = DynamicSimulationResult.Status.FAILED; - statusText = "Dynawo curves folder not found"; - } + setCurves(workingDir); } } else { status = DynamicSimulationResult.Status.FAILED; @@ -265,6 +221,61 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th return new DynamicSimulationResultImpl(status, statusText, curves, timeline); } + private void setDynawoLog(Path outputsFolder) { + Path logFile = outputsFolder.resolve(LOGS_FOLDER).resolve(LOGS_FILENAME); + if (Files.exists(logFile)) { + Reporter logReporter = CommonReports.createDynawoLogReporter(reporter); + new CsvLogParser().parse(logFile).forEach(e -> CommonReports.reportLogEvent(logReporter, e)); + } else { + LOGGER.warn("Dynawo logs file not found"); + } + } + + private void updateNetwork(Path outputsFolder) { + Path outputNetworkFile = outputsFolder.resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_IIDM_FILENAME); + if (Files.exists(outputNetworkFile)) { + NetworkResultsUpdater.update(context.getNetwork(), NetworkSerDe.read(outputNetworkFile), context.getDynaWaltzParameters().isMergeLoads()); + } else { + LOGGER.warn("Output IIDM file not found"); + status = DynamicSimulationResult.Status.FAILED; + statusText = "Dynawo Output IIDM file not found"; + } + } + + private void setDumpFile(Path outputsFolder, Path dumpFileFolder, Path fileName) throws IOException { + Path outputDumpFile = outputsFolder.resolve(FINAL_STATE_FOLDER).resolve(OUTPUT_DUMP_FILENAME); + if (Files.exists(outputDumpFile)) { + Files.copy(outputDumpFile, dumpFileFolder.resolve(fileName + "_" + OUTPUT_DUMP_FILENAME), StandardCopyOption.REPLACE_EXISTING); + } else { + LOGGER.warn("Dump file {} not found, export will be skipped", OUTPUT_DUMP_FILENAME); + } + } + + private void setTimeline(Path outputsFolder) { + Path timelineFile = outputsFolder.resolve(DYNAWO_TIMELINE_FOLDER).resolve(TIMELINE_FILENAME); + if (Files.exists(timelineFile)) { + Reporter timelineReporter = DynawaltzReports.createDynaWaltzTimelineReporter(reporter); + new CsvTimeLineParser().parse(timelineFile).forEach(e -> { + CommonReports.reportTimelineEvent(timelineReporter, e); + timeline.add(new TimelineEvent(e.time(), e.modelName(), e.message())); + }); + } else { + LOGGER.warn("Timeline file not found"); + } + } + + private void setCurves(Path workingDir) { + Path curvesPath = workingDir.resolve(CURVES_OUTPUT_PATH).toAbsolutePath().resolve(CURVES_FILENAME); + if (Files.exists(curvesPath)) { + Map> curvesPerVersion = TimeSeries.parseCsv(curvesPath, new TimeSeriesCsvConfig(TimeSeriesConstants.DEFAULT_SEPARATOR, false, TimeFormat.FRACTIONS_OF_SECOND)); + curvesPerVersion.values().forEach(l -> l.forEach(curve -> curves.put(curve.getMetadata().getName(), curve))); + } else { + LOGGER.warn("Curves folder not found"); + status = DynamicSimulationResult.Status.FAILED; + statusText = "Dynawo curves folder not found"; + } + } + private void writeInputFiles(Path workingDir) throws IOException { DynawoUtil.writeIidm(dynawoInput, workingDir.resolve(NETWORK_FILENAME)); JobsXml.write(workingDir, context); From cc88e1577962070a9c575788719faa2350e4ad8e Mon Sep 17 00:00:00 2001 From: lisrte Date: Mon, 4 Dec 2023 16:36:11 +0100 Subject: [PATCH 16/20] Rename DynamicSimulationResult.Status Signed-off-by: lisrte --- .../com/powsybl/dynawaltz/DynaWaltzProvider.java | 10 +++++----- .../java/com/powsybl/dynawo/it/DynaWaltzTest.java | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index 1708cab6f..8e605e9f6 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -157,7 +157,7 @@ private final class DynaWaltzHandler extends AbstractExecutionHandler timeline = new ArrayList<>(); private final Map curves = new HashMap<>(); - private DynamicSimulationResult.Status status = DynamicSimulationResult.Status.SUCCEED; + private DynamicSimulationResult.Status status = DynamicSimulationResult.Status.SUCCESS; private String statusText = ""; public DynaWaltzHandler(DynaWaltzContext context, Reporter reporter) { @@ -209,12 +209,12 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th setCurves(workingDir); } } else { - status = DynamicSimulationResult.Status.FAILED; + status = DynamicSimulationResult.Status.FAILURE; statusText = errorMatcher.group().substring(DYNAWO_ERROR_PATTERN.length()); } } else { LOGGER.warn("Error file not found"); - status = DynamicSimulationResult.Status.FAILED; + status = DynamicSimulationResult.Status.FAILURE; statusText = "Dynawo error log file not found"; } @@ -237,7 +237,7 @@ private void updateNetwork(Path outputsFolder) { NetworkResultsUpdater.update(context.getNetwork(), NetworkSerDe.read(outputNetworkFile), context.getDynaWaltzParameters().isMergeLoads()); } else { LOGGER.warn("Output IIDM file not found"); - status = DynamicSimulationResult.Status.FAILED; + status = DynamicSimulationResult.Status.FAILURE; statusText = "Dynawo Output IIDM file not found"; } } @@ -271,7 +271,7 @@ private void setCurves(Path workingDir) { curvesPerVersion.values().forEach(l -> l.forEach(curve -> curves.put(curve.getMetadata().getName(), curve))); } else { LOGGER.warn("Curves folder not found"); - status = DynamicSimulationResult.Status.FAILED; + status = DynamicSimulationResult.Status.FAILURE; statusText = "Dynawo curves folder not found"; } } diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java index 87dbd583d..e341a812f 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java @@ -84,7 +84,7 @@ void testIeee14() { VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); - assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); + assertEquals(DynamicSimulationResult.Status.SUCCESS, result.getStatus()); assertTrue(result.getStatusText().isEmpty()); assertEquals(41, result.getCurves().size()); DoubleTimeSeries ts1 = (DoubleTimeSeries) result.getCurve("_GEN____1_SM_generator_UStatorPu"); @@ -128,7 +128,7 @@ void testIeee14WithDump() throws IOException { DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); - assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); + assertEquals(DynamicSimulationResult.Status.SUCCESS, result.getStatus()); //Use exported dump as input parameters.setStartTime(30); @@ -144,7 +144,7 @@ void testIeee14WithDump() throws IOException { VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); - assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); + assertEquals(DynamicSimulationResult.Status.SUCCESS, result.getStatus()); } @Test @@ -168,7 +168,7 @@ void testSvc() { VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); - assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); + assertEquals(DynamicSimulationResult.Status.SUCCESS, result.getStatus()); assertTrue(result.getStatusText().isEmpty()); assertTrue(result.getCurves().isEmpty()); List timeLine = result.getTimeLine(); @@ -197,7 +197,7 @@ void testHvdc() { VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); - assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); + assertEquals(DynamicSimulationResult.Status.SUCCESS, result.getStatus()); assertTrue(result.getStatusText().isEmpty()); assertTrue(result.getCurves().isEmpty()); List timeLine = result.getTimeLine(); @@ -235,7 +235,7 @@ void testSmib() { VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); - assertEquals(DynamicSimulationResult.Status.SUCCEED, result.getStatus()); + assertEquals(DynamicSimulationResult.Status.SUCCESS, result.getStatus()); assertTrue(result.getStatusText().isEmpty()); assertEquals(35, result.getCurves().size()); List timeLine = result.getTimeLine(); @@ -265,7 +265,7 @@ void testSimulationError() { VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters, NO_OP) .join(); - assertEquals(DynamicSimulationResult.Status.FAILED, result.getStatus()); + assertEquals(DynamicSimulationResult.Status.FAILURE, result.getStatus()); assertEquals("time step <= 0.1 s for more than 10 iterations ( DYNSolverCommonFixedTimeStep.cpp:419 )", result.getStatusText()); assertTrue(result.getTimeLine().isEmpty()); assertTrue(result.getCurves().isEmpty()); From f7ec1abe42bb7ee9d6d93280d686d79e50ffcc0d Mon Sep 17 00:00:00 2001 From: lisrte Date: Tue, 5 Dec 2023 14:06:06 +0100 Subject: [PATCH 17/20] Fix review Signed-off-by: lisrte --- .../main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index 8e605e9f6..03263f655 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -23,6 +23,7 @@ import com.powsybl.dynawo.commons.timeline.CsvTimeLineParser; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.serde.NetworkSerDe; +import com.powsybl.timeseries.DoubleTimeSeries; import com.powsybl.timeseries.TimeSeries; import com.powsybl.timeseries.TimeSeries.TimeFormat; import com.powsybl.timeseries.TimeSeriesConstants; @@ -156,7 +157,7 @@ private final class DynaWaltzHandler extends AbstractExecutionHandler timeline = new ArrayList<>(); - private final Map curves = new HashMap<>(); + private final Map curves = new HashMap<>(); private DynamicSimulationResult.Status status = DynamicSimulationResult.Status.SUCCESS; private String statusText = ""; @@ -267,8 +268,8 @@ private void setTimeline(Path outputsFolder) { private void setCurves(Path workingDir) { Path curvesPath = workingDir.resolve(CURVES_OUTPUT_PATH).toAbsolutePath().resolve(CURVES_FILENAME); if (Files.exists(curvesPath)) { - Map> curvesPerVersion = TimeSeries.parseCsv(curvesPath, new TimeSeriesCsvConfig(TimeSeriesConstants.DEFAULT_SEPARATOR, false, TimeFormat.FRACTIONS_OF_SECOND)); - curvesPerVersion.values().forEach(l -> l.forEach(curve -> curves.put(curve.getMetadata().getName(), curve))); + TimeSeries.parseCsv(curvesPath, new TimeSeriesCsvConfig(TimeSeriesConstants.DEFAULT_SEPARATOR, false, TimeFormat.FRACTIONS_OF_SECOND)) + .values().forEach(l -> l.forEach(curve -> curves.put(curve.getMetadata().getName(), (DoubleTimeSeries) curve))); } else { LOGGER.warn("Curves folder not found"); status = DynamicSimulationResult.Status.FAILURE; From 8bbd6e584167e52af2552f71900d85a04acd430a Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Wed, 6 Dec 2023 11:10:04 +0100 Subject: [PATCH 18/20] Use optional instead of catched exception Signed-off-by: Florian Dupuy --- .../dynawo/commons/dynawologs/LogUtils.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java index d1ce67692..760c431de 100644 --- a/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java +++ b/commons/src/main/java/com/powsybl/dynawo/commons/dynawologs/LogUtils.java @@ -32,23 +32,22 @@ public static Optional createLog(String severity, String message) { if (emptyMessage(message)) { LOGGER.debug("Empty message, the entry will be skipped : {}", message); } else { - try { - return Optional.of(new LogEntry(convertDynawoLog(severity), message)); - } catch (IllegalArgumentException e) { - LOGGER.warn("Inconsistent severity entry '{}'", severity); - } + return convertDynawoLog(severity).map(severityTypedValue -> new LogEntry(severityTypedValue, message)); } } return Optional.empty(); } - private static TypedValue convertDynawoLog(String severity) { + private static Optional convertDynawoLog(String severity) { return switch (severity) { - case "DEBUG" -> TypedValue.DEBUG_SEVERITY; - case "INFO" -> TypedValue.INFO_SEVERITY; - case "WARN" -> TypedValue.WARN_SEVERITY; - case "ERROR" -> TypedValue.ERROR_SEVERITY; - default -> throw new IllegalArgumentException(); + case "DEBUG" -> Optional.of(TypedValue.DEBUG_SEVERITY); + case "INFO" -> Optional.of(TypedValue.INFO_SEVERITY); + case "WARN" -> Optional.of(TypedValue.WARN_SEVERITY); + case "ERROR" -> Optional.of(TypedValue.ERROR_SEVERITY); + default -> { + LOGGER.warn("Inconsistent severity entry '{}'", severity); + yield Optional.empty(); + } }; } From d2d66a9965e123ae0cc72ace85b7705616fdada4 Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Wed, 6 Dec 2023 11:24:56 +0100 Subject: [PATCH 19/20] Refer to v6.1.0 tag in the CI Signed-off-by: Florian Dupuy --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 6e256957c..d53531c66 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v1 with: repository: powsybl/powsybl-core - ref: refs/heads/main + ref: refs/tags/v6.1.0 - name: Checkout sources uses: actions/checkout@v1 From 4ca79f5af728bcff429d7631927b96cce9a349e9 Mon Sep 17 00:00:00 2001 From: Florian Dupuy Date: Wed, 6 Dec 2023 11:28:48 +0100 Subject: [PATCH 20/20] Bump powsybl-core to 6.1.0 Signed-off-by: Florian Dupuy --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 97274e31c..eb374f8ef 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 17 - 6.1.0-SNAPSHOT + 6.1.0 4.0.14 ../distribution/target/site/jacoco-aggregate/jacoco.xml,