diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/AbstractEquipmentModelBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/AbstractEquipmentModelBuilder.java index 18fe04d67..57319bce7 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/AbstractEquipmentModelBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/AbstractEquipmentModelBuilder.java @@ -18,7 +18,7 @@ /** * @author Laurent Issertial {@literal } */ -public abstract class AbstractEquipmentModelBuilder, R extends AbstractEquipmentModelBuilder> extends AbstractDynamicModelBuilder implements EquipmentModelBuilder { +public abstract class AbstractEquipmentModelBuilder, R extends AbstractEquipmentModelBuilder> extends AbstractDynamicModelBuilder implements EquipmentModelBuilder { protected String dynamicModelId; protected String parameterSetId; @@ -38,21 +38,25 @@ protected AbstractEquipmentModelBuilder(Network network, ModelConfig modelConfig this.builderEquipment = new BuilderEquipment<>(equipmentType); } + @Override public R staticId(String staticId) { builderEquipment.addEquipment(staticId, this::findEquipment); return self(); } + @Override public R equipment(T equipment) { builderEquipment.addEquipment(equipment, this::checkEquipment); return self(); } + @Override public R dynamicModelId(String dynamicModelId) { this.dynamicModelId = dynamicModelId; return self(); } + @Override public R parameterSetId(String parameterSetId) { this.parameterSetId = parameterSetId; return self(); diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderConfig.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderConfig.java index d5e3a3ef1..c4c5e9b5c 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderConfig.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderConfig.java @@ -24,14 +24,20 @@ public interface ModelBuilderConstructor { ModelBuilder createBuilder(Network network, String lib, ReportNode reportNode); } + private final String category; private final ModelBuilderConstructor builderConstructor; private final Supplier> libsSupplier; - public BuilderConfig(ModelBuilderConstructor builderConstructor, Supplier> libsSupplier) { + public BuilderConfig(String category, ModelBuilderConstructor builderConstructor, Supplier> libsSupplier) { + this.category = category; this.builderConstructor = builderConstructor; this.libsSupplier = libsSupplier; } + public String getCategory() { + return category; + } + public ModelBuilderConstructor getBuilderConstructor() { return builderConstructor; } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderEquipmentsList.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderEquipmentsList.java index 53d3bb6eb..5adcc74ee 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderEquipmentsList.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderEquipmentsList.java @@ -47,14 +47,16 @@ public void addEquipments(String[] staticIds, Function equipmentsSupp } public void addEquipments(Iterable staticIds, Function equipmentsSupplier) { - staticIds.forEach(id -> { - T equipment = equipmentsSupplier.apply(id); - if (equipment != null) { - equipments.add(equipment); - } else { - missingEquipmentIds.add(id); - } - }); + staticIds.forEach(id -> addEquipment(id, equipmentsSupplier)); + } + + public void addEquipment(String staticId, Function equipmentsSupplier) { + T equipment = equipmentsSupplier.apply(staticId); + if (equipment != null) { + equipments.add(equipment); + } else { + missingEquipmentIds.add(staticId); + } } public boolean checkEquipmentData(ReportNode reportNode) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderReports.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderReports.java index 19f6791c4..0e399d6fc 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderReports.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/BuilderReports.java @@ -21,6 +21,14 @@ public final class BuilderReports { private BuilderReports() { } + public static void reportBuilderNotFound(ReportNode reportNode, String lib) { + reportNode.newReportNode() + .withMessageTemplate("builderNotFound", "No builder found for ${lib}") + .withUntypedValue("lib", lib) + .withSeverity(TypedValue.INFO_SEVERITY) + .add(); + } + public static void reportLibNotFound(ReportNode reportNode, String builderName, String lib) { reportNode.newReportNode() .withMessageTemplate("libNotFound", "Library ${lib} not found for ${builderName}") @@ -40,7 +48,7 @@ public static void reportModelInstantiation(ReportNode reportNode, String dynami public static void reportModelInstantiationFailure(ReportNode reportNode, String dynamicId) { reportNode.newReportNode() - .withMessageTemplate("modelInstantiation", "Model ${dynamicId} cannot be instantiated") + .withMessageTemplate("modelInstantiationError", "Model ${dynamicId} cannot be instantiated") .withUntypedValue("dynamicId", dynamicId) .withSeverity(TypedValue.WARN_SEVERITY) .add(); diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/EquipmentModelBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/EquipmentModelBuilder.java index 3cf218abd..97db380ed 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/EquipmentModelBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/EquipmentModelBuilder.java @@ -8,14 +8,17 @@ package com.powsybl.dynawaltz.builders; import com.powsybl.dynamicsimulation.DynamicModel; +import com.powsybl.iidm.network.Identifiable; /** * @author Laurent Issertial {@literal } */ -public interface EquipmentModelBuilder> extends ModelBuilder { +public interface EquipmentModelBuilder, R extends EquipmentModelBuilder> extends ModelBuilder { R staticId(String staticId); + R equipment(T equipment); + R dynamicModelId(String dynamicModelId); R parameterSetId(String parameterSetId); diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigLoaderImpl.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigLoaderImpl.java index a2c1bdb06..2728e4426 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigLoaderImpl.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigLoaderImpl.java @@ -36,31 +36,30 @@ public final class ModelConfigLoaderImpl implements ModelConfigLoader { private static final String MODEL_CONFIG_FILENAME = "models.json"; private static final Stream BUILDER_CONFIGS = Stream.of( - new BuilderConfig(DynamicOverloadManagementSystemBuilder::of, DynamicOverloadManagementSystemBuilder::getSupportedLibs), - new BuilderConfig(DynamicTwoLevelsOverloadManagementSystemBuilder::of, DynamicTwoLevelsOverloadManagementSystemBuilder::getSupportedLibs), - new BuilderConfig(TapChangerAutomationSystemBuilder::of, TapChangerAutomationSystemBuilder::getSupportedLibs), - new BuilderConfig(TapChangerBlockingAutomationSystemBuilder::of, TapChangerBlockingAutomationSystemBuilder::getSupportedLibs), - new BuilderConfig(UnderVoltageAutomationSystemBuilder::of, UnderVoltageAutomationSystemBuilder::getSupportedLibs), - new BuilderConfig(PhaseShifterPAutomationSystemBuilder::of, PhaseShifterPAutomationSystemBuilder::getSupportedLibs), - new BuilderConfig(PhaseShifterIAutomationSystemBuilder::of, PhaseShifterIAutomationSystemBuilder::getSupportedLibs), - new BuilderConfig(StandardBusBuilder::of, StandardBusBuilder::getSupportedLibs), - new BuilderConfig(InfiniteBusBuilder::of, InfiniteBusBuilder::getSupportedLibs), - new BuilderConfig(TransformerFixedRatioBuilder::of, TransformerFixedRatioBuilder::getSupportedLibs), - new BuilderConfig(LineBuilder::of, LineBuilder::getSupportedLibs), - new BuilderConfig(HvdcVscBuilder::of, HvdcVscBuilder::getSupportedLibs), - new BuilderConfig(HvdcPBuilder::of, HvdcPBuilder::getSupportedLibs), - new BuilderConfig(BaseLoadBuilder::of, BaseLoadBuilder::getSupportedLibs), - new BuilderConfig(LoadOneTransformerBuilder::of, LoadOneTransformerBuilder::getSupportedLibs), - new BuilderConfig(LoadOneTransformerTapChangerBuilder::of, LoadOneTransformerTapChangerBuilder::getSupportedLibs), - new BuilderConfig(LoadTwoTransformersBuilder::of, LoadTwoTransformersBuilder::getSupportedLibs), - new BuilderConfig(LoadTwoTransformersTapChangersBuilder::of, LoadTwoTransformersTapChangersBuilder::getSupportedLibs), - new BuilderConfig(BaseStaticVarCompensatorBuilder::of, BaseStaticVarCompensatorBuilder::getSupportedLibs), - new BuilderConfig(GeneratorFictitiousBuilder::of, GeneratorFictitiousBuilder::getSupportedLibs), - new BuilderConfig(SynchronizedGeneratorBuilder::of, SynchronizedGeneratorBuilder::getSupportedLibs), - new BuilderConfig(SynchronousGeneratorBuilder::of, SynchronousGeneratorBuilder::getSupportedLibs), - new BuilderConfig(WeccBuilder::of, WeccBuilder::getSupportedLibs), - new BuilderConfig(GridFormingConverterBuilder::of, GridFormingConverterBuilder::getSupportedLibs), - new BuilderConfig(GeneratorFictitiousBuilder::of, GeneratorFictitiousBuilder::getSupportedLibs)); + new BuilderConfig(DynamicOverloadManagementSystemBuilder.CATEGORY, DynamicOverloadManagementSystemBuilder::of, DynamicOverloadManagementSystemBuilder::getSupportedLibs), + new BuilderConfig(DynamicTwoLevelsOverloadManagementSystemBuilder.CATEGORY, DynamicTwoLevelsOverloadManagementSystemBuilder::of, DynamicTwoLevelsOverloadManagementSystemBuilder::getSupportedLibs), + new BuilderConfig(TapChangerAutomationSystemBuilder.CATEGORY, TapChangerAutomationSystemBuilder::of, TapChangerAutomationSystemBuilder::getSupportedLibs), + new BuilderConfig(TapChangerBlockingAutomationSystemBuilder.CATEGORY, TapChangerBlockingAutomationSystemBuilder::of, TapChangerBlockingAutomationSystemBuilder::getSupportedLibs), + new BuilderConfig(UnderVoltageAutomationSystemBuilder.CATEGORY, UnderVoltageAutomationSystemBuilder::of, UnderVoltageAutomationSystemBuilder::getSupportedLibs), + new BuilderConfig(PhaseShifterPAutomationSystemBuilder.CATEGORY, PhaseShifterPAutomationSystemBuilder::of, PhaseShifterPAutomationSystemBuilder::getSupportedLibs), + new BuilderConfig(PhaseShifterIAutomationSystemBuilder.CATEGORY, PhaseShifterIAutomationSystemBuilder::of, PhaseShifterIAutomationSystemBuilder::getSupportedLibs), + new BuilderConfig(StandardBusBuilder.CATEGORY, StandardBusBuilder::of, StandardBusBuilder::getSupportedLibs), + new BuilderConfig(InfiniteBusBuilder.CATEGORY, InfiniteBusBuilder::of, InfiniteBusBuilder::getSupportedLibs), + new BuilderConfig(TransformerFixedRatioBuilder.CATEGORY, TransformerFixedRatioBuilder::of, TransformerFixedRatioBuilder::getSupportedLibs), + new BuilderConfig(LineBuilder.CATEGORY, LineBuilder::of, LineBuilder::getSupportedLibs), + new BuilderConfig(HvdcVscBuilder.CATEGORY, HvdcVscBuilder::of, HvdcVscBuilder::getSupportedLibs), + new BuilderConfig(HvdcPBuilder.CATEGORY, HvdcPBuilder::of, HvdcPBuilder::getSupportedLibs), + new BuilderConfig(BaseLoadBuilder.CATEGORY, BaseLoadBuilder::of, BaseLoadBuilder::getSupportedLibs), + new BuilderConfig(LoadOneTransformerBuilder.CATEGORY, LoadOneTransformerBuilder::of, LoadOneTransformerBuilder::getSupportedLibs), + new BuilderConfig(LoadOneTransformerTapChangerBuilder.CATEGORY, LoadOneTransformerTapChangerBuilder::of, LoadOneTransformerTapChangerBuilder::getSupportedLibs), + new BuilderConfig(LoadTwoTransformersBuilder.CATEGORY, LoadTwoTransformersBuilder::of, LoadTwoTransformersBuilder::getSupportedLibs), + new BuilderConfig(LoadTwoTransformersTapChangersBuilder.CATEGORY, LoadTwoTransformersTapChangersBuilder::of, LoadTwoTransformersTapChangersBuilder::getSupportedLibs), + new BuilderConfig(BaseStaticVarCompensatorBuilder.CATEGORY, BaseStaticVarCompensatorBuilder::of, BaseStaticVarCompensatorBuilder::getSupportedLibs), + new BuilderConfig(GeneratorFictitiousBuilder.CATEGORY, GeneratorFictitiousBuilder::of, GeneratorFictitiousBuilder::getSupportedLibs), + new BuilderConfig(SynchronizedGeneratorBuilder.CATEGORY, SynchronizedGeneratorBuilder::of, SynchronizedGeneratorBuilder::getSupportedLibs), + new BuilderConfig(SynchronousGeneratorBuilder.CATEGORY, SynchronousGeneratorBuilder::of, SynchronousGeneratorBuilder::getSupportedLibs), + new BuilderConfig(WeccBuilder.CATEGORY, WeccBuilder::of, WeccBuilder::getSupportedLibs), + new BuilderConfig(GridFormingConverterBuilder.CATEGORY, GridFormingConverterBuilder::of, GridFormingConverterBuilder::getSupportedLibs)); @Override public String getModelConfigFileName() { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigsHandler.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigsHandler.java index 284938126..fa0575e50 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigsHandler.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/builders/ModelConfigsHandler.java @@ -8,9 +8,13 @@ package com.powsybl.dynawaltz.builders; import com.google.common.collect.Lists; +import com.powsybl.commons.report.ReportNode; +import com.powsybl.dynamicsimulation.DynamicModel; +import com.powsybl.dynamicsimulation.EventModel; import com.powsybl.dynawaltz.models.events.EventActivePowerVariationBuilder; import com.powsybl.dynawaltz.models.events.EventDisconnectionBuilder; import com.powsybl.dynawaltz.models.events.NodeFaultEventBuilder; +import com.powsybl.iidm.network.Network; import java.util.HashMap; import java.util.List; @@ -25,13 +29,20 @@ public final class ModelConfigsHandler { private static final ModelConfigsHandler INSTANCE = new ModelConfigsHandler(); private final Map modelConfigsCat = new HashMap<>(); - private final List builderConfigs; + private final Map builderConstructorByName = new HashMap<>(); + private final List eventBuilderConfigs = List.of( new EventBuilderConfig(EventActivePowerVariationBuilder::of, EventActivePowerVariationBuilder.TAG), new EventBuilderConfig(EventDisconnectionBuilder::of, EventDisconnectionBuilder.TAG), new EventBuilderConfig(NodeFaultEventBuilder::of, NodeFaultEventBuilder.TAG)); + private final Map eventBuilderConstructorByName = Map.of( + EventDisconnectionBuilder.TAG, EventDisconnectionBuilder::of, + NodeFaultEventBuilder.TAG, EventDisconnectionBuilder::of, + EventActivePowerVariationBuilder.TAG, EventActivePowerVariationBuilder::of + ); + private ModelConfigsHandler() { List modelConfigLoaders = Lists.newArrayList(ServiceLoader.load(ModelConfigLoader.class)); modelConfigLoaders.forEach(l -> l.loadModelConfigs().forEach( @@ -41,6 +52,8 @@ private ModelConfigsHandler() { }) )); builderConfigs = modelConfigLoaders.stream().flatMap(ModelConfigLoader::loadBuilderConfigs).toList(); + builderConfigs.forEach(bc -> modelConfigsCat.get(bc.getCategory()).getSupportedLibs() + .forEach(lib -> builderConstructorByName.put(lib, bc.getBuilderConstructor()))); } public static ModelConfigsHandler getInstance() { @@ -58,4 +71,22 @@ public List getBuilderConfigs() { public List getEventBuilderConfigs() { return eventBuilderConfigs; } + + public ModelBuilder getModelBuilder(Network network, String modelName, ReportNode reportNode) { + BuilderConfig.ModelBuilderConstructor constructor = builderConstructorByName.get(modelName); + if (constructor == null) { + BuilderReports.reportBuilderNotFound(reportNode, modelName); + return null; + } + return constructor.createBuilder(network, modelName, reportNode); + } + + public ModelBuilder getEventModelBuilder(Network network, String modelName, ReportNode reportNode) { + EventBuilderConfig.EventModelBuilderConstructor constructor = eventBuilderConstructorByName.get(modelName); + if (constructor == null) { + BuilderReports.reportBuilderNotFound(reportNode, modelName); + return null; + } + return constructor.createBuilder(network, reportNode); + } } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/TapChangerAutomationSystemBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/TapChangerAutomationSystemBuilder.java index e21202d25..a38065cea 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/TapChangerAutomationSystemBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/TapChangerAutomationSystemBuilder.java @@ -21,7 +21,7 @@ */ public class TapChangerAutomationSystemBuilder extends AbstractAutomationSystemModelBuilder { - private static final String CATEGORY = "tapChangers"; + public static final String CATEGORY = "TAP_CHANGER"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); protected final BuilderEquipment load; diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/TapChangerBlockingAutomationSystemBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/TapChangerBlockingAutomationSystemBuilder.java index 1147038a9..38798cd03 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/TapChangerBlockingAutomationSystemBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/TapChangerBlockingAutomationSystemBuilder.java @@ -20,7 +20,7 @@ */ public class TapChangerBlockingAutomationSystemBuilder extends AbstractAutomationSystemModelBuilder { - private static final String CATEGORY = "tcbs"; + public static final String CATEGORY = "TAP_CHANGER_BLOCKING"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); private static final String TAP_CHANGER_TYPE = IdentifiableType.TWO_WINDINGS_TRANSFORMER + "/" + IdentifiableType.LOAD; private static final String U_MEASUREMENTS_FIELD = "uMeasurements"; @@ -60,6 +60,11 @@ protected TapChangerBlockingAutomationSystemBuilder(Network network, ModelConfig uMeasurementPoints = new BuilderIdListEquipmentList<>(MEASUREMENT_POINT_TYPE, U_MEASUREMENTS_FIELD); } + public TapChangerBlockingAutomationSystemBuilder transformers(String staticId) { + tapChangerEquipments.addEquipment(staticId, id -> this.getTapChangerEquipment(network, id)); + return self(); + } + public TapChangerBlockingAutomationSystemBuilder transformers(String... staticIds) { tapChangerEquipments.addEquipments(staticIds, id -> this.getTapChangerEquipment(network, id)); return self(); @@ -75,6 +80,11 @@ private Identifiable getTapChangerEquipment(Network network, String staticId) return tapChangerEquipment != null ? tapChangerEquipment : network.getLoad(staticId); } + public TapChangerBlockingAutomationSystemBuilder uMeasurements(String staticId) { + uMeasurementPoints.addEquipment(staticId, id -> BuildersUtil.getActionConnectionPoint(network, id)); + return self(); + } + public TapChangerBlockingAutomationSystemBuilder uMeasurements(String... staticIds) { uMeasurementPoints.addEquipments(staticIds, id -> BuildersUtil.getActionConnectionPoint(network, id)); return self(); diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/UnderVoltageAutomationSystemBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/UnderVoltageAutomationSystemBuilder.java index 874558819..4310ecdb1 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/UnderVoltageAutomationSystemBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/UnderVoltageAutomationSystemBuilder.java @@ -24,7 +24,7 @@ */ public class UnderVoltageAutomationSystemBuilder extends AbstractAutomationSystemModelBuilder { - private static final String CATEGORY = "underVoltages"; + public static final String CATEGORY = "UNDER_VOLTAGE"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); protected final BuilderEquipment generator; diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/overloadmanagments/DynamicOverloadManagementSystemBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/overloadmanagments/DynamicOverloadManagementSystemBuilder.java index ea0bdd6ee..47e23a1f6 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/overloadmanagments/DynamicOverloadManagementSystemBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/overloadmanagments/DynamicOverloadManagementSystemBuilder.java @@ -23,7 +23,7 @@ */ public class DynamicOverloadManagementSystemBuilder extends AbstractOverloadManagementSystemBuilder { - private static final String CATEGORY = "overloadManagements"; + public static final String CATEGORY = "OVERLOAD_MANAGEMENT"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static DynamicOverloadManagementSystemBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/overloadmanagments/DynamicTwoLevelsOverloadManagementSystemBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/overloadmanagments/DynamicTwoLevelsOverloadManagementSystemBuilder.java index f3650abe4..311c5b323 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/overloadmanagments/DynamicTwoLevelsOverloadManagementSystemBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/overloadmanagments/DynamicTwoLevelsOverloadManagementSystemBuilder.java @@ -24,7 +24,7 @@ */ public class DynamicTwoLevelsOverloadManagementSystemBuilder extends AbstractOverloadManagementSystemBuilder { - private static final String CATEGORY = "twoLevelsOverloadManagements"; + public static final String CATEGORY = "TWO_LEVEL_OVERLOAD_MANAGEMENT"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); protected final BuilderEquipment> iMeasurement2; diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/phaseshifters/PhaseShifterIAutomationSystemBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/phaseshifters/PhaseShifterIAutomationSystemBuilder.java index c8e0cb55d..889c22015 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/phaseshifters/PhaseShifterIAutomationSystemBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/phaseshifters/PhaseShifterIAutomationSystemBuilder.java @@ -21,7 +21,7 @@ */ public class PhaseShifterIAutomationSystemBuilder extends AbstractPhaseShifterModelBuilder { - private static final String CATEGORY = "phaseShiftersI"; + public static final String CATEGORY = "PHASE_SHIFTER_I"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static PhaseShifterIAutomationSystemBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/phaseshifters/PhaseShifterPAutomationSystemBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/phaseshifters/PhaseShifterPAutomationSystemBuilder.java index 341b80859..6189cbde3 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/phaseshifters/PhaseShifterPAutomationSystemBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/automationsystems/phaseshifters/PhaseShifterPAutomationSystemBuilder.java @@ -21,7 +21,7 @@ */ public class PhaseShifterPAutomationSystemBuilder extends AbstractPhaseShifterModelBuilder { - private static final String CATEGORY = "phaseShiftersP"; + public static final String CATEGORY = "PHASE_SHIFTER_P"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static PhaseShifterPAutomationSystemBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/InfiniteBusBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/InfiniteBusBuilder.java index bf050fb8e..b45545145 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/InfiniteBusBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/InfiniteBusBuilder.java @@ -21,7 +21,7 @@ */ public class InfiniteBusBuilder extends AbstractBusBuilder { - private static final String CATEGORY = "infiniteBuses"; + public static final String CATEGORY = "INFINITE_BUS"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static InfiniteBusBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/StandardBusBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/StandardBusBuilder.java index 271c4d7b0..e8529ba80 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/StandardBusBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/buses/StandardBusBuilder.java @@ -21,7 +21,7 @@ */ public class StandardBusBuilder extends AbstractBusBuilder { - private static final String CATEGORY = "baseBuses"; + public static final String CATEGORY = "BASE_BUS"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static StandardBusBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorFictitiousBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorFictitiousBuilder.java index 9023abdac..a61a8783b 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorFictitiousBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorFictitiousBuilder.java @@ -21,7 +21,7 @@ */ public class GeneratorFictitiousBuilder extends AbstractGeneratorBuilder { - private static final String CATEGORY = "baseGenerators"; + public static final String CATEGORY = "BASE_GENERATOR"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static GeneratorFictitiousBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GridFormingConverterBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GridFormingConverterBuilder.java index eb6f27ea5..dddfc1fea 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GridFormingConverterBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GridFormingConverterBuilder.java @@ -21,7 +21,7 @@ */ public class GridFormingConverterBuilder extends AbstractGeneratorBuilder { - private static final String CATEGORY = "gridFormingConverters"; + public static final String CATEGORY = "GRID_FORMING_CONVERTER"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static GridFormingConverterBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/SynchronizedGeneratorBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/SynchronizedGeneratorBuilder.java index 91284f660..0ba9c7a2e 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/SynchronizedGeneratorBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/SynchronizedGeneratorBuilder.java @@ -21,7 +21,7 @@ */ public class SynchronizedGeneratorBuilder extends AbstractGeneratorBuilder { - private static final String CATEGORY = "synchronizedGenerators"; + public static final String CATEGORY = "SYNCHRONIZED_GENERATOR"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static SynchronizedGeneratorBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/SynchronousGeneratorBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/SynchronousGeneratorBuilder.java index 0918c9a1e..ec14ec64a 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/SynchronousGeneratorBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/SynchronousGeneratorBuilder.java @@ -22,7 +22,7 @@ */ public class SynchronousGeneratorBuilder extends AbstractGeneratorBuilder { - private static final String CATEGORY = "synchronousGenerators"; + public static final String CATEGORY = "SYNCHRONOUS_GENERATOR"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static SynchronousGeneratorBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/WeccBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/WeccBuilder.java index 884582a43..a8aaa03b1 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/WeccBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/WeccBuilder.java @@ -21,7 +21,7 @@ */ public class WeccBuilder extends AbstractGeneratorBuilder { - private static final String CATEGORY = "wecc"; + public static final String CATEGORY = "WECC"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static WeccBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/hvdc/HvdcPBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/hvdc/HvdcPBuilder.java index e0f33948f..0f92bb440 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/hvdc/HvdcPBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/hvdc/HvdcPBuilder.java @@ -23,7 +23,7 @@ */ public class HvdcPBuilder extends AbstractHvdcBuilder { - private static final String CATEGORY = "hvdcP"; + public static final String CATEGORY = "HVDC_P"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static HvdcPBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/hvdc/HvdcVscBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/hvdc/HvdcVscBuilder.java index bbc361573..f66d8319d 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/hvdc/HvdcVscBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/hvdc/HvdcVscBuilder.java @@ -22,7 +22,7 @@ */ public class HvdcVscBuilder extends AbstractHvdcBuilder { - private static final String CATEGORY = "hvdcVsc"; + public static final String CATEGORY = "HVDC_VSC"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); private static final Predicate IS_VSC = eq -> HvdcConverterStation.HvdcType.VSC == eq.getConverterStation1().getHvdcType(); diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/lines/LineBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/lines/LineBuilder.java index 3247d3ec8..d536bd886 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/lines/LineBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/lines/LineBuilder.java @@ -24,7 +24,7 @@ */ public class LineBuilder extends AbstractEquipmentModelBuilder { - private static final String CATEGORY = "baseLines"; + public static final String CATEGORY = "BASE_LINE"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static LineBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/BaseLoadBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/BaseLoadBuilder.java index 9dc771202..859c90ed7 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/BaseLoadBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/BaseLoadBuilder.java @@ -21,7 +21,7 @@ */ public class BaseLoadBuilder extends AbstractLoadModelBuilder { - private static final String CATEGORY = "baseLoads"; + public static final String CATEGORY = "BASE_LOAD"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static BaseLoadBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadOneTransformerBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadOneTransformerBuilder.java index 582d3b6d0..3c485ad8a 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadOneTransformerBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadOneTransformerBuilder.java @@ -21,7 +21,7 @@ */ public class LoadOneTransformerBuilder extends AbstractLoadModelBuilder { - private static final String CATEGORY = "loadsOneTransformer"; + public static final String CATEGORY = "LOAD_ONE_TRANSFORMER"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static LoadOneTransformerBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadOneTransformerTapChangerBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadOneTransformerTapChangerBuilder.java index e89afd04d..ef938f90e 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadOneTransformerTapChangerBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadOneTransformerTapChangerBuilder.java @@ -21,7 +21,7 @@ */ public class LoadOneTransformerTapChangerBuilder extends AbstractLoadModelBuilder { - private static final String CATEGORY = "loadsOneTransformerTapChanger"; + public static final String CATEGORY = "LOAD_ONE_TRANSFORMER_TAP_CHANGER"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static LoadOneTransformerTapChangerBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadTwoTransformersBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadTwoTransformersBuilder.java index fcfa723f6..26e91f153 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadTwoTransformersBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadTwoTransformersBuilder.java @@ -21,7 +21,7 @@ */ public class LoadTwoTransformersBuilder extends AbstractLoadModelBuilder { - private static final String CATEGORY = "loadsTwoTransformers"; + public static final String CATEGORY = "LOAD_TWO_TRANSFORMERS"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static LoadTwoTransformersBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadTwoTransformersTapChangersBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadTwoTransformersTapChangersBuilder.java index 352591fdf..911d79cce 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadTwoTransformersTapChangersBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadTwoTransformersTapChangersBuilder.java @@ -21,7 +21,7 @@ */ public class LoadTwoTransformersTapChangersBuilder extends AbstractLoadModelBuilder { - private static final String CATEGORY = "loadsTwoTransformersTapChanger"; + public static final String CATEGORY = "LOAD_TWO_TRANSFORMERS_TAP_CHANGER"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static LoadTwoTransformersTapChangersBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/svarcs/BaseStaticVarCompensatorBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/svarcs/BaseStaticVarCompensatorBuilder.java index fd5976458..5b68ebefc 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/svarcs/BaseStaticVarCompensatorBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/svarcs/BaseStaticVarCompensatorBuilder.java @@ -24,7 +24,7 @@ */ public class BaseStaticVarCompensatorBuilder extends AbstractEquipmentModelBuilder { - private static final String CATEGORY = "staticVarCompensators"; + public static final String CATEGORY = "BASE_STATIC_VAR_COMPENSATOR"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static BaseStaticVarCompensatorBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/transformers/TransformerFixedRatioBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/transformers/TransformerFixedRatioBuilder.java index 3f08e0fd4..a34be77c1 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/transformers/TransformerFixedRatioBuilder.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/transformers/TransformerFixedRatioBuilder.java @@ -24,7 +24,7 @@ */ public class TransformerFixedRatioBuilder extends AbstractEquipmentModelBuilder { - private static final String CATEGORY = "transformers"; + public static final String CATEGORY = "TRANSFORMER"; private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY); public static TransformerFixedRatioBuilder of(Network network) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/Property.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/Property.java new file mode 100644 index 000000000..73e383e67 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/Property.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2024, 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.suppliers; + + +/** + * {@link com.powsybl.dynawaltz.suppliers.dynamicmodels.DynamicModelConfig} and {@link com.powsybl.dynawaltz.suppliers.events.EventModelConfig} property + * @param name property name corresponding to {@link com.powsybl.dynawaltz.builders.ModelBuilder} method name + * @param value property value + * @param propertyClass {@link #value} class + * @author Laurent Issertial {@literal } + */ +public record Property(String name, Object value, Class propertyClass) { +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/PropertyBuilder.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/PropertyBuilder.java new file mode 100644 index 000000000..b15b689d3 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/PropertyBuilder.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2024, 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.suppliers; + +import com.powsybl.dynawaltz.suppliers.dynamicmodels.DynamicModelConfigsJsonDeserializer; +import com.powsybl.dynawaltz.suppliers.events.EventModelConfigsJsonDeserializer; + +import java.util.Collection; +import java.util.List; + +/** + * Builds {@link Property} in configuration Json deserializers + * @see DynamicModelConfigsJsonDeserializer + * @see EventModelConfigsJsonDeserializer + * @author Laurent Issertial {@literal } + */ +public class PropertyBuilder { + + private String name; + private String value; + private List values; + private List> arrays; + private PropertyType type; + private CollectionType collectionType = CollectionType.SINGLE; + + private enum CollectionType { + SINGLE, + LIST, + LIST_ARRAY + } + + public Property build() { + return switch (collectionType) { + case SINGLE -> new Property(name, type.isConversionFree() ? value : type.convertValue(value), type.getPropertyClass()); + case LIST -> new Property(name, type.isConversionFree() ? values : values.stream().map(v -> type.convertValue(v)).toList(), Collection.class); + case LIST_ARRAY -> new Property(name, type.isConversionFree() ? + arrays.toArray(List[]::new) : + arrays.stream().map(vl -> vl.stream().map(v -> type.convertValue(v)).toList()).toArray(List[]::new), + Collection[].class); + }; + } + + public PropertyBuilder name(String name) { + this.name = name; + return this; + } + + public PropertyBuilder value(String value) { + collectionType = CollectionType.SINGLE; + this.value = value; + return this; + } + + public PropertyBuilder values(List values) { + collectionType = CollectionType.LIST; + this.values = values; + return this; + } + + public PropertyBuilder arrays(List> arrays) { + collectionType = CollectionType.LIST_ARRAY; + this.arrays = arrays; + return this; + } + + public PropertyBuilder type(PropertyType type) { + this.type = type; + return this; + } +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/PropertyParserUtils.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/PropertyParserUtils.java new file mode 100644 index 000000000..b610ef1b3 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/PropertyParserUtils.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2024, 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.suppliers; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.powsybl.commons.PowsyblException; +import com.powsybl.commons.json.JsonUtil; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Laurent Issertial {@literal } + */ +public final class PropertyParserUtils { + + private PropertyParserUtils() { + } + + public static Property parseProperty(JsonParser parser) { + PropertyBuilder builder = new PropertyBuilder(); + JsonUtil.parseObject(parser, name -> { + boolean handled = true; + switch (name) { + case "name" -> builder.name(parser.nextTextValue()); + case "value" -> builder.value(parser.nextTextValue()); + case "values" -> builder.values(JsonUtil.parseStringArray(parser)); + case "arrays" -> parseArrays(parser, builder); + case "type" -> builder.type(PropertyType.valueOf(parser.nextTextValue())); + default -> handled = false; + } + return handled; + }); + return builder.build(); + } + + private static void parseArrays(JsonParser parser, PropertyBuilder builder) throws IOException { + parser.nextToken(); + parser.nextToken(); + JsonToken token; + List> arrays = new ArrayList<>(); + List values = new ArrayList<>(); + while ((token = parser.nextToken()) != null) { + if (token == JsonToken.VALUE_STRING) { + values.add(parser.getText()); + } else if (token == JsonToken.END_ARRAY) { + arrays.add(values); + JsonToken next = parser.nextToken(); + if (next == JsonToken.END_ARRAY) { + builder.arrays(arrays); + break; + } else if (next == JsonToken.START_ARRAY) { + values = new ArrayList<>(); + } else { + throw new PowsyblException("Unexpected token " + next); + } + } else { + throw new PowsyblException("Unexpected token " + token); + } + } + } +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/PropertyType.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/PropertyType.java new file mode 100644 index 000000000..9b03f5995 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/PropertyType.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2024, 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.suppliers; + +import com.powsybl.iidm.network.TwoSides; + +import java.util.function.Function; + +/** + * @author Laurent Issertial {@literal } + */ +public enum PropertyType { + + TWO_SIDES(TwoSides.class, TwoSides::valueOf), + BOOLEAN(boolean.class, Boolean::parseBoolean), + INTEGER(int.class, Integer::parseInt), + DOUBLE(double.class, Double::parseDouble), + STRING(String.class, value -> value); + + private final Class propertyClass; + private final Function valueConvertor; + + PropertyType(Class propertyClass, Function valueConvertor) { + this.propertyClass = propertyClass; + this.valueConvertor = valueConvertor; + } + + public Class getPropertyClass() { + return propertyClass; + } + + public Object convertValue(String value) { + return valueConvertor.apply(value); + } + + public boolean isConversionFree() { + return this == STRING; + } +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/SetGroupType.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/SetGroupType.java new file mode 100644 index 000000000..5e10323fd --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/SetGroupType.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2024, 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.suppliers; + +import com.powsybl.dynawaltz.suppliers.dynamicmodels.DynawoModelsSupplier; + +/** + * Configures {@link com.powsybl.dynawaltz.suppliers.dynamicmodels.DynamicModelConfig#group()} processing in {@link DynawoModelsSupplier} + * @author Laurent Issertial {@literal } + */ +public enum SetGroupType { + /** + * group is used as a parameter set id + */ + FIXED, + /** + * the parameter set id comprise the model dynamic id (or the equipment static id if not found) prefixed by group + */ + PREFIX, + /** + * the parameter set id comprise the model dynamic id (or the equipment static id if not found) suffixed by group + */ + SUFFIX +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/dynamicmodels/DynamicModelConfig.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/dynamicmodels/DynamicModelConfig.java new file mode 100644 index 000000000..b053b6756 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/dynamicmodels/DynamicModelConfig.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2024, 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.suppliers.dynamicmodels; + +import com.powsybl.dynawaltz.suppliers.Property; +import com.powsybl.dynawaltz.suppliers.SetGroupType; + +import java.util.List; + +/** + * Dynamic model configuration deserialized by {@link DynamicModelConfigsJsonDeserializer} + * used to configure dynamic model builder in {@link DynawoModelsSupplier} + * @param model alias of the library used for this model + * @param group represents model parameter set id or part of it depending on {@link #groupType} + * @param groupType configures {@link #group} processing + * @param properties list of properties used by the builder + * @author Laurent Issertial {@literal } + */ +public record DynamicModelConfig(String model, String group, SetGroupType groupType, List properties) { + + public DynamicModelConfig(String model, String group, List properties) { + this(model, group, SetGroupType.FIXED, properties); + } +} + diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/dynamicmodels/DynamicModelConfigsJsonDeserializer.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/dynamicmodels/DynamicModelConfigsJsonDeserializer.java new file mode 100644 index 000000000..b9b4ba5c4 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/dynamicmodels/DynamicModelConfigsJsonDeserializer.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2024, 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.suppliers.dynamicmodels; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.powsybl.commons.json.JsonUtil; +import com.powsybl.dynawaltz.suppliers.Property; +import com.powsybl.dynawaltz.suppliers.PropertyParserUtils; +import com.powsybl.dynawaltz.suppliers.SetGroupType; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Laurent Issertial {@literal } + */ +public class DynamicModelConfigsJsonDeserializer extends StdDeserializer> { + + public DynamicModelConfigsJsonDeserializer() { + super(List.class); + } + + @Override + public List deserialize(JsonParser parser, DeserializationContext context) { + List modelConfigList = new ArrayList<>(); + JsonUtil.parseObject(parser, name -> { + if (name.equals("models")) { + JsonUtil.parseObjectArray(parser, modelConfigList::add, DynamicModelConfigsJsonDeserializer::parseModelConfig); + return true; + } + return false; + }); + return modelConfigList; + } + + private static DynamicModelConfig parseModelConfig(JsonParser parser) { + var parsingContext = new Object() { + String model = null; + String group = null; + SetGroupType groupType = SetGroupType.FIXED; + final List properties = new ArrayList<>(); + }; + JsonUtil.parseObject(parser, name -> { + boolean handled = true; + switch (name) { + case "model" -> parsingContext.model = parser.nextTextValue(); + case "group" -> parsingContext.group = parser.nextTextValue(); + case "groupType" -> parsingContext.groupType = SetGroupType.valueOf(parser.nextTextValue()); + case "properties" -> JsonUtil.parseObjectArray(parser, parsingContext.properties::add, PropertyParserUtils::parseProperty); + default -> handled = false; + } + return handled; + }); + return new DynamicModelConfig(parsingContext.model, parsingContext.group, parsingContext.groupType, parsingContext.properties); + } +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/dynamicmodels/DynawoModelsSupplier.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/dynamicmodels/DynawoModelsSupplier.java new file mode 100644 index 000000000..5398282c3 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/dynamicmodels/DynawoModelsSupplier.java @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2024, 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.suppliers.dynamicmodels; + +import com.powsybl.commons.PowsyblException; +import com.powsybl.commons.report.ReportNode; +import com.powsybl.dynamicsimulation.DynamicModel; +import com.powsybl.dynamicsimulation.DynamicModelsSupplier; +import com.powsybl.dynawaltz.builders.ModelBuilder; +import com.powsybl.dynawaltz.builders.ModelConfigsHandler; +import com.powsybl.dynawaltz.suppliers.Property; +import com.powsybl.iidm.network.Network; + +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.Objects; + +/** + * Instantiates an {@link DynamicModelConfig} list from {@link DynamicModelConfig} + * @author Laurent Issertial {@literal } + */ +public class DynawoModelsSupplier implements DynamicModelsSupplier { + + private static final String PARAMETER_ID_FIELD = "parameterSetId"; + + private final List dynamicModelConfigs; + + public DynawoModelsSupplier(List dynamicModelConfigs) { + this.dynamicModelConfigs = dynamicModelConfigs; + } + + @Override + public List get(Network network, ReportNode reportNode) { + return dynamicModelConfigs.stream() + .map(dynamicModelConfig -> buildDynamicModel(dynamicModelConfig, network, reportNode)) + .filter(Objects::nonNull) + .toList(); + } + + private static DynamicModel buildDynamicModel(DynamicModelConfig dynamicModelConfig, Network network, ReportNode reportNode) { + ModelBuilder builder = ModelConfigsHandler.getInstance().getModelBuilder(network, dynamicModelConfig.model(), reportNode); + if (builder != null) { + Class builderClass = builder.getClass(); + invokeParameterIdMethod(builderClass, builder, getParameterSetId(dynamicModelConfig)); + dynamicModelConfig.properties().forEach(p -> invokeMethod(builderClass, builder, p)); + return builder.build(); + } + return null; + } + + private static void invokeMethod(Class builderClass, ModelBuilder builder, Property property) { + try { + builderClass.getMethod(property.name(), property.propertyClass()).invoke(builder, property.value()); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new PowsyblException(String.format("Method %s not found for parameter %s on builder %s", property.name(), property.value(), builderClass.getSimpleName()), e); + } + } + + private static void invokeParameterIdMethod(Class builderClass, ModelBuilder builder, String parameterSetId) { + try { + builderClass.getMethod(DynawoModelsSupplier.PARAMETER_ID_FIELD, String.class).invoke(builder, parameterSetId); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new PowsyblException(String.format("Method %s not found for parameter %s on builder %s", DynawoModelsSupplier.PARAMETER_ID_FIELD, parameterSetId, builderClass.getSimpleName()), e); + } + } + + private static String getParameterSetId(DynamicModelConfig config) { + return switch (config.groupType()) { + case FIXED -> config.group(); + case PREFIX -> config.group() + getDynamicModelIdProperty(config.properties()); + case SUFFIX -> getDynamicModelIdProperty(config.properties()) + config.group(); + }; + } + + private static String getDynamicModelIdProperty(List properties) { + return properties.stream() + .filter(p -> p.name().equalsIgnoreCase("dynamicModelId")) + .map(p -> (String) p.value()) + .findFirst() + .orElseGet(() -> getStaticIdProperty(properties)); + } + + private static String getStaticIdProperty(List properties) { + return properties.stream() + .filter(p -> p.name().equalsIgnoreCase("staticId")) + .map(p -> (String) p.value()) + .findFirst() + .orElseThrow(() -> new PowsyblException("No ID found for parameter set id")); + } +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/events/DynawoEventModelsSupplier.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/events/DynawoEventModelsSupplier.java new file mode 100644 index 000000000..8162bfabf --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/events/DynawoEventModelsSupplier.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2024, 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.suppliers.events; + +import com.powsybl.commons.PowsyblException; +import com.powsybl.commons.report.ReportNode; +import com.powsybl.dynamicsimulation.EventModel; +import com.powsybl.dynamicsimulation.EventModelsSupplier; +import com.powsybl.dynawaltz.builders.ModelBuilder; +import com.powsybl.dynawaltz.builders.ModelConfigsHandler; +import com.powsybl.dynawaltz.suppliers.Property; +import com.powsybl.iidm.network.Network; + +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.Objects; + +/** + * Instantiates an {@link EventModel} list from {@link EventModelConfig} + * @author Laurent Issertial {@literal } + */ +public class DynawoEventModelsSupplier implements EventModelsSupplier { + + private final List eventModelConfigs; + + public DynawoEventModelsSupplier(List eventModelConfigs) { + this.eventModelConfigs = eventModelConfigs; + } + + @Override + public List get(Network network, ReportNode reportNode) { + return eventModelConfigs.stream() + .map(eventModelConfig -> buildEventModel(eventModelConfig, network, reportNode)) + .filter(Objects::nonNull) + .toList(); + } + + private static EventModel buildEventModel(EventModelConfig eventModelConfig, Network network, ReportNode reportNode) { + ModelBuilder builder = ModelConfigsHandler.getInstance().getEventModelBuilder(network, eventModelConfig.model(), reportNode); + if (builder != null) { + Class builderClass = builder.getClass(); + eventModelConfig.properties().forEach(p -> invokeMethod(builderClass, builder, p)); + return builder.build(); + } + return null; + } + + private static void invokeMethod(Class builderClass, ModelBuilder builder, Property property) { + try { + builderClass.getMethod(property.name(), property.propertyClass()).invoke(builder, property.value()); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new PowsyblException(String.format("Method %s not found for parameter %s on builder %s", property.name(), property.value(), builderClass.getSimpleName()), e); + } + } +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/events/EventModelConfig.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/events/EventModelConfig.java new file mode 100644 index 000000000..79dbf701b --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/events/EventModelConfig.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2024, 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.suppliers.events; + +import com.powsybl.dynawaltz.suppliers.Property; + +import java.util.List; + +/** + * Event model configuration deserialized by {@link EventModelConfigsJsonDeserializer} + * used to configure event model builder in {@link DynawoEventModelsSupplier} + * @param model alias of the library used for this model + * @param properties list of properties used by the builder + * @author Laurent Issertial {@literal } + */ +public record EventModelConfig(String model, List properties) { +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/events/EventModelConfigsJsonDeserializer.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/events/EventModelConfigsJsonDeserializer.java new file mode 100644 index 000000000..781c17f1e --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/suppliers/events/EventModelConfigsJsonDeserializer.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2024, 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.suppliers.events; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.powsybl.commons.json.JsonUtil; +import com.powsybl.dynawaltz.suppliers.Property; +import com.powsybl.dynawaltz.suppliers.PropertyParserUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author Laurent Issertial {@literal } + */ +public class EventModelConfigsJsonDeserializer extends StdDeserializer> { + + public EventModelConfigsJsonDeserializer() { + super(List.class); + } + + @Override + public List deserialize(JsonParser parser, DeserializationContext context) { + List modelConfigList = new ArrayList<>(); + JsonUtil.parseObject(parser, name -> { + if (name.equals("events")) { + JsonUtil.parseObjectArray(parser, modelConfigList::add, EventModelConfigsJsonDeserializer::parseModelConfig); + return true; + } + return false; + }); + return modelConfigList; + } + + private static EventModelConfig parseModelConfig(JsonParser parser) { + var parsingContext = new Object() { + String model = null; + final List properties = new ArrayList<>(); + }; + JsonUtil.parseObject(parser, name -> { + boolean handled = true; + switch (name) { + case "model" -> parsingContext.model = parser.nextTextValue(); + case "properties" -> JsonUtil.parseObjectArray(parser, parsingContext.properties::add, PropertyParserUtils::parseProperty); + default -> handled = false; + } + return handled; + }); + return new EventModelConfig(parsingContext.model, parsingContext.properties); + } +} diff --git a/dynawaltz/src/main/resources/models.json b/dynawaltz/src/main/resources/models.json index 145fb6eaa..ecc7115a3 100644 --- a/dynawaltz/src/main/resources/models.json +++ b/dynawaltz/src/main/resources/models.json @@ -1,5 +1,5 @@ { - "baseGenerators": { + "BASE_GENERATOR": { "defaultLib": "GeneratorFictitious", "libs": [ { @@ -7,7 +7,7 @@ } ] }, - "synchronousGenerators": { + "SYNCHRONOUS_GENERATOR": { "defaultLib": "GeneratorSynchronousFourWindings", "libs": [ { @@ -183,7 +183,7 @@ } ] }, - "synchronizedGenerators": { + "SYNCHRONIZED_GENERATOR": { "defaultLib": "GeneratorPQ", "libs": [ { @@ -203,7 +203,7 @@ } ] }, - "hvdcP": { + "HVDC_P": { "defaultLib": "HvdcPV", "libs": [ { @@ -292,7 +292,7 @@ } ] }, - "hvdcVsc": { + "HVDC_VSC": { "defaultLib": "HvdcVSC", "libs": [ { @@ -315,7 +315,7 @@ } ] }, - "baseBuses": { + "BASE_BUS": { "defaultLib": "Bus", "libs": [ { @@ -323,7 +323,7 @@ } ] }, - "infiniteBuses": { + "INFINITE_BUS": { "defaultLib": "InfiniteBus", "libs": [ { @@ -337,7 +337,7 @@ } ] }, - "baseLoads": { + "BASE_LOAD": { "defaultLib": "LoadAlphaBeta", "libs": [ { @@ -384,7 +384,7 @@ } ] }, - "loadsOneTransformer": { + "LOAD_ONE_TRANSFORMER": { "defaultLib": "LoadOneTransformer", "libs": [ { @@ -392,7 +392,7 @@ } ] }, - "loadsOneTransformerTapChanger": { + "LOAD_ONE_TRANSFORMER_TAP_CHANGER": { "defaultLib": "LoadOneTransformerTapChanger", "libs": [ { @@ -400,7 +400,7 @@ } ] }, - "loadsTwoTransformers": { + "LOAD_TWO_TRANSFORMERS": { "defaultLib": "LoadTwoTransformers", "libs": [ { @@ -408,7 +408,7 @@ } ] }, - "loadsTwoTransformersTapChanger": { + "LOAD_TWO_TRANSFORMERS_TAP_CHANGER": { "defaultLib": "LoadTwoTransformersTapChangers", "libs": [ { @@ -416,7 +416,7 @@ } ] }, - "baseLines": { + "BASE_LINE": { "defaultLib": "Line", "libs": [ { @@ -424,7 +424,7 @@ } ] }, - "staticVarCompensators": { + "BASE_STATIC_VAR_COMPENSATOR": { "defaultLib": "StaticVarCompensator", "libs": [ { @@ -456,7 +456,7 @@ } ] }, - "transformers": { + "TRANSFORMER": { "defaultLib": "TransformerFixedRatio", "libs": [ { @@ -467,7 +467,7 @@ } ] }, - "wecc": { + "WECC": { "defaultLib": "WTG4AWeccCurrentSource", "libs": [ { @@ -508,7 +508,7 @@ } ] }, - "gridFormingConverters": { + "GRID_FORMING_CONVERTER": { "defaultLib": "GridFormingConverterDroopControl", "libs": [ { @@ -531,7 +531,7 @@ } ] }, - "overloadManagements": { + "OVERLOAD_MANAGEMENT": { "defaultLib": "OverloadManagementSystem", "libs": [ { @@ -540,7 +540,7 @@ } ] }, - "twoLevelsOverloadManagements": { + "TWO_LEVEL_OVERLOAD_MANAGEMENT": { "defaultLib": "TwoLevelsOverloadManagementSystem", "libs": [ { @@ -549,7 +549,7 @@ } ] }, - "phaseShiftersI": { + "PHASE_SHIFTER_I": { "defaultLib": "PhaseShifterI", "libs": [ { @@ -557,7 +557,7 @@ } ] }, - "phaseShiftersP": { + "PHASE_SHIFTER_P": { "defaultLib": "PhaseShifterP", "libs": [ { @@ -565,7 +565,7 @@ } ] }, - "tapChangers": { + "TAP_CHANGER": { "defaultLib": "TapChangerAutomaton", "libs": [ { @@ -573,7 +573,7 @@ } ] }, - "tcbs": { + "TAP_CHANGER_BLOCKING": { "defaultLib": "TapChangerBlockingAutomaton", "libs": [ { @@ -581,7 +581,7 @@ } ] }, - "underVoltages": { + "UNDER_VOLTAGE": { "defaultLib": "UnderVoltage", "libs": [ { diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/suppliers/DynawoEventModelsSuppliersTest.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/suppliers/DynawoEventModelsSuppliersTest.java new file mode 100644 index 000000000..98c4838d7 --- /dev/null +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/suppliers/DynawoEventModelsSuppliersTest.java @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2024, 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.suppliers; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.powsybl.commons.PowsyblException; +import com.powsybl.commons.report.ReportNode; +import com.powsybl.dynamicsimulation.EventModel; +import com.powsybl.dynawaltz.models.events.EventActivePowerVariationBuilder; +import com.powsybl.dynawaltz.models.events.EventDisconnectionBuilder; +import com.powsybl.dynawaltz.suppliers.events.*; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.TwoSides; +import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Laurent Issertial {@literal } + */ +class DynawoEventModelsSuppliersTest { + + @Test + void testEventSupplier() { + Network network = EurostagTutorialExample1Factory.create(); + List eventModelConfigList = getEventConfigs(); + List events = new DynawoEventModelsSupplier(eventModelConfigList).get(network, ReportNode.NO_OP); + + EventModel disconnection = EventDisconnectionBuilder.of(network) + .staticId("NHV1_NHV2_2") + .startTime(1) + .disconnectOnly(TwoSides.TWO) + .build(); + EventModel step = EventActivePowerVariationBuilder.of(network) + .staticId("LOAD") + .startTime(1) + .deltaP(20) + .build(); + + assertEquals(2, events.size()); + assertThat(events.get(0)).usingRecursiveComparison().isEqualTo(disconnection); + assertThat(events.get(1)).usingRecursiveComparison().isEqualTo(step); + } + + @Test + void testWrongNameBuilder() { + Network network = EurostagTutorialExample1Factory.create(); + List eventModelConfigList = List.of( + new EventModelConfig("WrongName", Collections.emptyList()) + ); + List events = new DynawoEventModelsSupplier(eventModelConfigList).get(network, ReportNode.NO_OP); + assertTrue(events.isEmpty()); + } + + @Test + void testEventModelConfigDeserializer() throws IOException { + ObjectMapper objectMapper = setupObjectMapper(); + try (InputStream is = getClass().getResourceAsStream("/suppliers/mappingEvent.json")) { + List configs = objectMapper.readValue(is, new TypeReference<>() { + }); + assertEquals(1, configs.size()); + assertThat(configs.get(0)).usingRecursiveComparison().isEqualTo(getActivePowerVariationConfig()); + } + } + + @Test + void wrongPropertyException() { + Network network = EurostagTutorialExample1Factory.create(); + EventModelConfig eventModelConfig = new EventModelConfig("Disconnect", List.of( + new PropertyBuilder() + .name("wrongName") + .value("NHV1_NHV2_2") + .type(PropertyType.STRING) + .build() + )); + DynawoEventModelsSupplier supplier = new DynawoEventModelsSupplier(List.of(eventModelConfig)); + Exception e = assertThrows(PowsyblException.class, () -> supplier.get(network, ReportNode.NO_OP)); + assertEquals("Method wrongName not found for parameter NHV1_NHV2_2 on builder EventDisconnectionBuilder", e.getMessage()); + } + + private static List getEventConfigs() { + return List.of( + new EventModelConfig("Disconnect", List.of( + new PropertyBuilder() + .name("staticId") + .value("NHV1_NHV2_2") + .type(PropertyType.STRING) + .build(), + new PropertyBuilder() + .name("startTime") + .value("1") + .type(PropertyType.DOUBLE) + .build(), + new PropertyBuilder() + .name("disconnectOnly") + .value("TWO") + .type(PropertyType.TWO_SIDES) + .build() + )), + getActivePowerVariationConfig() + ); + } + + private static EventModelConfig getActivePowerVariationConfig() { + return new EventModelConfig("Step", List.of( + new PropertyBuilder() + .name("staticId") + .value("LOAD") + .type(PropertyType.STRING) + .build(), + new PropertyBuilder() + .name("startTime") + .value("1") + .type(PropertyType.DOUBLE) + .build(), + new PropertyBuilder() + .name("deltaP") + .value("20") + .type(PropertyType.DOUBLE) + .build())); + } + + private static ObjectMapper setupObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + SimpleModule module = new SimpleModule(); + module.addDeserializer(List.class, new EventModelConfigsJsonDeserializer()); + objectMapper.registerModule(module); + return objectMapper; + } +} diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/suppliers/DynawoModelsSuppliersTest.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/suppliers/DynawoModelsSuppliersTest.java new file mode 100644 index 000000000..22a02f7c4 --- /dev/null +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/suppliers/DynawoModelsSuppliersTest.java @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2024, 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.suppliers; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.powsybl.commons.PowsyblException; +import com.powsybl.commons.report.ReportNode; +import com.powsybl.dynamicsimulation.DynamicModel; +import com.powsybl.dynawaltz.models.automationsystems.TapChangerBlockingAutomationSystemBuilder; +import com.powsybl.dynawaltz.models.generators.SynchronizedGeneratorBuilder; +import com.powsybl.dynawaltz.suppliers.dynamicmodels.DynamicModelConfig; +import com.powsybl.dynawaltz.suppliers.dynamicmodels.*; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Laurent Issertial {@literal } + */ +class DynawoModelsSuppliersTest { + + @Test + void testDynamicModelSupplier() { + Network network = EurostagTutorialExample1Factory.createWithLFResults(); + List modelConfigList = getModelConfigs(); + List models = new DynawoModelsSupplier(modelConfigList).get(network, ReportNode.NO_OP); + + DynamicModel gen = SynchronizedGeneratorBuilder.of(network, "GeneratorPQ") + .staticId("GEN") + .parameterSetId("DM_GEN") + .build(); + DynamicModel tcb = TapChangerBlockingAutomationSystemBuilder.of(network) + .dynamicModelId("TCB1") + .parameterSetId("tcb_par") + .transformers("NGEN_NHV1", "NHV2_NLOAD") + .uMeasurements(new Collection[]{List.of("OldNGen", "NGEN"), List.of("NHV1", "NHV2")}) + .build(); + DynamicModel tcb2 = TapChangerBlockingAutomationSystemBuilder.of(network) + .dynamicModelId("TCB2") + .parameterSetId("tcb_par") + .transformers("NGEN_NHV2") + .uMeasurements("NHV2") + .build(); + + assertEquals(3, models.size()); + assertThat(models.get(0)).usingRecursiveComparison().isEqualTo(gen); + assertThat(models.get(1)).usingRecursiveComparison().isEqualTo(tcb); + assertThat(models.get(2)).usingRecursiveComparison().isEqualTo(tcb2); + } + + @Test + void testWrongNameBuilder() { + Network network = EurostagTutorialExample1Factory.create(); + List modelConfigList = List.of( + new DynamicModelConfig("WrongName", "param", Collections.emptyList()) + ); + List models = new DynawoModelsSupplier(modelConfigList).get(network, ReportNode.NO_OP); + assertTrue(models.isEmpty()); + } + + @Test + void testModelConfigDeserializer() throws IOException { + ObjectMapper objectMapper = setupObjectMapper(); + try (InputStream is = getClass().getResourceAsStream("/suppliers/mappingDynamicModel.json")) { + List configs = objectMapper.readValue(is, new TypeReference<>() { + }); + assertEquals(2, configs.size()); + assertThat(configs.get(0)).usingRecursiveComparison().isEqualTo(getLoadConfig()); + assertThat(configs.get(1)).usingRecursiveComparison().isEqualTo(getTcbConfig()); + } + } + + @Test + void groupTypeException() { + Network network = EurostagTutorialExample1Factory.create(); + List properties = List.of( + new PropertyBuilder() + .name("propertyName") + .value("LOAD") + .type(PropertyType.STRING) + .build()); + DynamicModelConfig modelConfig = new DynamicModelConfig("LoadAlphaBeta", "_DM", SetGroupType.SUFFIX, properties); + DynawoModelsSupplier supplier = new DynawoModelsSupplier(List.of(modelConfig)); + PowsyblException e = assertThrows(PowsyblException.class, () -> supplier.get(network)); + assertEquals("No ID found for parameter set id", e.getMessage()); + } + + @Test + void wrongPropertyException() { + Network network = EurostagTutorialExample1Factory.create(); + DynamicModelConfig modelConfig = new DynamicModelConfig("LoadAlphaBeta", "LAB", List.of( + new PropertyBuilder() + .name("wrongName") + .value("LOAD") + .type(PropertyType.STRING) + .build() + )); + DynawoModelsSupplier supplier = new DynawoModelsSupplier(List.of(modelConfig)); + Exception e = assertThrows(PowsyblException.class, () -> supplier.get(network, ReportNode.NO_OP)); + assertEquals("Method wrongName not found for parameter LOAD on builder BaseLoadBuilder", e.getMessage()); + } + + private static List getModelConfigs() { + return List.of( + new DynamicModelConfig("GeneratorPQ", "DM_", SetGroupType.PREFIX, List.of( + new PropertyBuilder() + .name("staticId") + .value("GEN") + .type(PropertyType.STRING) + .build())), + getTcbConfig(), + getSimpleTcbConfig() + ); + } + + private static DynamicModelConfig getLoadConfig() { + return new DynamicModelConfig("LoadAlphaBeta", "_DM", SetGroupType.SUFFIX, List.of( + new PropertyBuilder() + .name("staticId") + .value("LOAD") + .type(PropertyType.STRING) + .build())); + } + + private static DynamicModelConfig getTcbConfig() { + return new DynamicModelConfig("TapChangerBlockingAutomaton", "tcb_par", SetGroupType.FIXED, List.of( + new PropertyBuilder() + .name("dynamicModelId") + .value("TCB1") + .type(PropertyType.STRING) + .build(), + new PropertyBuilder() + .name("transformers") + .values(List.of("NGEN_NHV1", "NHV2_NLOAD")) + .type(PropertyType.STRING) + .build(), + new PropertyBuilder() + .name("uMeasurements") + .arrays(List.of(List.of("OldNGen", "NGEN"), List.of("NHV1", "NHV2"))) + .type(PropertyType.STRING) + .build() + )); + } + + private static DynamicModelConfig getSimpleTcbConfig() { + return new DynamicModelConfig("TapChangerBlockingAutomaton", "tcb_par", SetGroupType.FIXED, List.of( + new PropertyBuilder() + .name("dynamicModelId") + .value("TCB2") + .type(PropertyType.STRING) + .build(), + new PropertyBuilder() + .name("transformers") + .value("NGEN_NHV2") + .type(PropertyType.STRING) + .build(), + new PropertyBuilder() + .name("uMeasurements") + .value("NHV2") + .type(PropertyType.STRING) + .build() + )); + } + + private static ObjectMapper setupObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + SimpleModule module = new SimpleModule(); + module.addDeserializer(List.class, new DynamicModelConfigsJsonDeserializer()); + objectMapper.registerModule(module); + return objectMapper; + } +} diff --git a/dynawaltz/src/test/resources/suppliers/mappingDynamicModel.json b/dynawaltz/src/test/resources/suppliers/mappingDynamicModel.json new file mode 100644 index 000000000..2801a92fb --- /dev/null +++ b/dynawaltz/src/test/resources/suppliers/mappingDynamicModel.json @@ -0,0 +1,37 @@ +{ + "models":[ + { + "model":"LoadAlphaBeta", + "group": "_DM", + "groupType": "SUFFIX", + "properties":[ + { + "name":"staticId", + "value":"LOAD", + "type":"STRING" + } + ] + }, + { + "model": "TapChangerBlockingAutomaton", + "group": "tcb_par", + "properties":[ + { + "name": "dynamicModelId", + "value": "TCB1", + "type": "STRING" + }, + { + "name": "transformers", + "values": ["NGEN_NHV1", "NHV2_NLOAD"], + "type": "STRING" + }, + { + "name": "uMeasurements", + "arrays": [["OldNGen", "NGEN"], ["NHV1", "NHV2"]], + "type": "STRING" + } + ] + } + ] +} \ No newline at end of file diff --git a/dynawaltz/src/test/resources/suppliers/mappingEvent.json b/dynawaltz/src/test/resources/suppliers/mappingEvent.json new file mode 100644 index 000000000..f33c3749c --- /dev/null +++ b/dynawaltz/src/test/resources/suppliers/mappingEvent.json @@ -0,0 +1,24 @@ +{ + "events":[ + { + "model":"Step", + "properties":[ + { + "name":"staticId", + "value":"LOAD", + "type":"STRING" + }, + { + "name":"startTime", + "value":"1", + "type":"DOUBLE" + }, + { + "name":"deltaP", + "value":"20", + "type":"DOUBLE" + } + ] + } + ] +} \ No newline at end of file