From c646a5bdb6d9060c7bdda86bb2d5a068b9e71870 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Sun, 24 Oct 2021 16:40:10 +0200 Subject: [PATCH 01/24] include models into processed grid --- .../main/RunConversion.scala | 2 +- .../model/PreprocessedPfGridModel.scala | 88 ++++++++++++++++--- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala b/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala index 0024fdc4..a91e5f0e 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala @@ -37,6 +37,6 @@ object RunConversion extends LazyLogging { .getOrElse( throw GridParsingException("Parsing the Json grid file failed") ) - val psdmGrid = GridConverter.convert(pfGrid) + val psdmGrid = GridConverter.convert(pfGrid, config) } } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala index 45789268..7b5c4602 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala @@ -7,6 +7,7 @@ package edu.ie3.powerFactory2psdm.model import com.typesafe.scalalogging.LazyLogging +import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.ParameterSource import edu.ie3.powerFactory2psdm.exception.pf.{ ConversionException, GridConfigurationException, @@ -15,13 +16,24 @@ import edu.ie3.powerFactory2psdm.exception.pf.{ import edu.ie3.powerFactory2psdm.model.RawPfGridModel.{ LineTypes, Lines, + Loads, + LoadsLV, + LoadsMV, Nodes, ProjectSettings, + StatGen, Switches, TrafoTypes2w, Trafos2w } -import edu.ie3.powerFactory2psdm.model.entity.{Line, Node, Switch} +import edu.ie3.powerFactory2psdm.model.entity.{ + Line, + Load, + Node, + StaticGenerator, + Switch, + Transformer2W +} import edu.ie3.powerFactory2psdm.model.entity.types.{ LineType, Transformer2WType @@ -54,7 +66,10 @@ final case class PreprocessedPfGridModel( lineTypes: List[LineType], lines: List[Line], switches: List[Switch], + transformers2W: List[Transformer2W], transformerTypes2W: List[Transformer2WType], + loads: List[Load], + staticGenerators: List[StaticGenerator], conversionPrefixes: ConversionPrefixes ) @@ -68,7 +83,11 @@ object PreprocessedPfGridModel extends LazyLogging { * @return * the preprocessed PowerFactory grid model */ - def build(rawGrid: RawPfGridModel): PreprocessedPfGridModel = { + def build( + rawGrid: RawPfGridModel, + sRatedSource: ParameterSource, + cosPhiSource: ParameterSource + ): PreprocessedPfGridModel = { val projectSettings = extractProjectSettings(rawGrid.projectSettings) checkUnitSystem( projectSettings.unitSystem.getOrElse( @@ -82,28 +101,35 @@ object PreprocessedPfGridModel extends LazyLogging { throw GridConfigurationException("There are no nodes in the grid.") ) val rawLines = rawGrid.lines.getOrElse({ - logger.debug("There are no lines in the grid.") + logger debug "There are no lines in the grid." List.empty[Lines] }) val rawLineTypes = rawGrid.lineTypes.getOrElse({ - logger.debug("There are no lines in the grid.") + logger debug "There are no lines in the grid." List.empty[LineTypes] }) val rawSwitches = rawGrid.switches.getOrElse({ - logger.debug("There are no switches in the grid.") + logger debug "There are no switches in the grid." List.empty[Switches] }) val rawTrafos2W = rawGrid.trafos2w.getOrElse({ - logger.debug("There are no switches in the grid.") + logger debug "There are no switches in the grid." List.empty[Trafos2w] }) val rawTrafoTpyes2W = rawGrid.trafoTypes2w.getOrElse({ - logger.debug("There are no 2w trafo types in the grid.") + logger debug "There are no 2w trafo types in the grid." List.empty[TrafoTypes2w] }) + val rawLoads = + (rawGrid.loads ++ rawGrid.loadsLV ++ rawGrid.loadsMV).flatten.toList + if (rawLoads.isEmpty) logger debug "There are no loads in the grid." + val rawStaticGenerators = rawGrid.statGen.getOrElse({ + logger debug "There are no static generators in the grid." + List.empty[StatGen] + }) val models = - rawNodes ++ rawLines ++ rawLineTypes ++ rawSwitches ++ rawTrafos2W ++ rawTrafoTpyes2W + rawNodes ++ rawLines ++ rawLineTypes ++ rawSwitches ++ rawTrafos2W ++ rawTrafoTpyes2W ++ rawLoads ++ rawStaticGenerators val modelIds = models.map { case node: Nodes => node.id.getOrElse( @@ -129,10 +155,34 @@ object PreprocessedPfGridModel extends LazyLogging { s"Transformer $trafo2w has no defined id" ) ) - case trafoTypes2w: TrafoTypes2w => - trafoTypes2w.id.getOrElse( + case trafoType2w: TrafoTypes2w => + trafoType2w.id.getOrElse( + throw MissingParameterException( + s"Transformer type $trafoType2w has no defined id" + ) + ) + case load: Loads => + load.id.getOrElse( + throw MissingParameterException( + s"Load $load has no defined id" + ) + ) + case load: LoadsLV => + load.id.getOrElse( + throw MissingParameterException( + s"LV load $load has no defined id" + ) + ) + case load: LoadsMV => + load.id.getOrElse( + throw MissingParameterException( + s"MV load $load has no defined id" + ) + ) + case staticGenerator: StatGen => + staticGenerator.id.getOrElse( throw MissingParameterException( - s"Transformer type $trafoTypes2w has no defined id" + s"Static generator $staticGenerator has no defined id" ) ) } @@ -148,14 +198,30 @@ object PreprocessedPfGridModel extends LazyLogging { val lines = rawLines.map(line => Line.build(line)) val lineTypes = rawLineTypes.map(LineType.build) val switches = rawSwitches.flatMap(Switch.maybeBuild) + val transformers2W = rawTrafos2W.map(Transformer2W.build) val trafoTypes2W = rawTrafoTpyes2W.map(Transformer2WType.build) + val loads = rawLoads.map { + case load: Loads => Load.build(load) + case load: LoadsLV => Load.build(load) + case load: LoadsMV => Load.build(load) + case other => + throw ConversionException( + s"Encountered unexpected load type: $other. I hate surprises!" + ) + } + val staticGenerators = rawStaticGenerators.map(statGen => + StaticGenerator.build(statGen, sRatedSource, cosPhiSource) + ) PreprocessedPfGridModel( nodes, lineTypes, lines, switches, + transformers2W, trafoTypes2W, + loads, + staticGenerators, conversionPrefixes ) } From 19a05840a8e9abee8e8a2d41b60a292714c9be59 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Mon, 25 Oct 2021 12:18:22 +0200 Subject: [PATCH 02/24] convert models --- .../converter/GridConverter.scala | 26 ++++++++-- .../converter/LoadConverter.scala | 12 +++++ .../converter/StaticGeneratorConverter.scala | 28 +++++++++++ .../converter/Transformer2WConverter.scala | 50 +++++++++++++++++-- .../types/Transformer2WTypeConverter.scala | 9 ++-- .../model/entity/StaticGenerator.scala | 8 ++- 6 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala index fca0164d..9f582b82 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala @@ -6,7 +6,9 @@ package edu.ie3.powerFactory2psdm.converter -import edu.ie3.powerFactory2psdm.converter.types.LineTypeConverter +import edu.ie3.powerFactory2psdm.config.ConversionConfig +import edu.ie3.powerFactory2psdm.config.ConversionConfig.StatGenModelConfigs +import edu.ie3.powerFactory2psdm.converter.types.{LineTypeConverter, Transformer2WTypeConverter} import edu.ie3.powerFactory2psdm.model.{PreprocessedPfGridModel, RawPfGridModel} /** Functionalities to transform an exported and then parsed PowerFactory grid @@ -14,8 +16,12 @@ import edu.ie3.powerFactory2psdm.model.{PreprocessedPfGridModel, RawPfGridModel} */ case object GridConverter { - def convert(pfGrid: RawPfGridModel) = { - val grid = PreprocessedPfGridModel.build(pfGrid) + def convert(pfGrid: RawPfGridModel, config: ConversionConfig) = { + val grid = PreprocessedPfGridModel.build( + pfGrid, + config.modelConfigs.sRatedSource, + config.modelConfigs.cosPhiSource + ) val gridElements = convertGridElements(grid) } @@ -25,7 +31,8 @@ case object GridConverter { * the raw parsed PowerFactoryGrid */ def convertGridElements( - grid: PreprocessedPfGridModel + grid: PreprocessedPfGridModel, + statGenConversionConfig: StatGenModelConfigs ): Unit = { val graph = GridGraphBuilder.build(grid.nodes, grid.lines ++ grid.switches) @@ -41,5 +48,16 @@ case object GridConverter { nodes, lineTypes ) + val transformer2WTypes = grid.transformerTypes2W + .map(transformer => + transformer.id -> Transformer2WTypeConverter.convert(transformer) + ) + .toMap + val transfomers2W = Transformer2WConverter.convertTransformers( + grid.transformers2W, + nodes, + transformer2WTypes + ) + val loads = LoadConverter.convertLoads(grid.loads, nodes) } } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala index d76e17d0..e783e1b1 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala @@ -10,6 +10,7 @@ import edu.ie3.datamodel.models.{BdewLoadProfile, OperationTime} import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed +import edu.ie3.powerFactory2psdm.converter.NodeConverter.getNode import edu.ie3.powerFactory2psdm.exception.pf.ConversionException import edu.ie3.powerFactory2psdm.model.entity.Load import edu.ie3.util.quantities.PowerSystemUnits.{KILOWATTHOUR, MEGAVOLTAMPERE} @@ -20,6 +21,17 @@ import scala.util.{Failure, Success} object LoadConverter { + def convertLoads(input: List[Load], nodes: Map[String, NodeInput]): List[LoadInput] = { + input map { load => + getNode(load.nodeId, nodes) match { + case Success(node) => convert(load, node) + case Failure(exc) => throw ConversionException( + s"Could not convert load due to inability of finding its converted node with id: ${load.nodeId}", exc + ) + } + } + } + def convert(input: Load, node: NodeInput): LoadInput = { val id = input.id val cosPhi = ConversionHelper.determineCosPhiRated( diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala new file mode 100644 index 00000000..acc48865 --- /dev/null +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala @@ -0,0 +1,28 @@ +package edu.ie3.powerFactory2psdm.converter + +import edu.ie3.datamodel.models.input.system.{FixedFeedInInput, PvInput, WecInput} +import edu.ie3.powerFactory2psdm.config.ConversionConfig.StatGenModelConfigs +import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator + +object StaticGeneratorConverter { + + /*** + * Container class to house the different PSDM models resulting from the conversion of the [[StaticGenerator]]s + * + * @param fixedFeedIns fixed feed ins + * @param pvInputs pv models + * @param wecInputs wec models + */ + final case class StatGenModelContainer( + fixedFeedIns: List[FixedFeedInInput], + pvInputs: List[PvInput], + wecInputs: List[WecInput] + ) + + def convert(input: List[StaticGenerator], conversionConfig: StatGenModelConfigs): StatGenModelContainer = { + input.map(statGen => statGen.category match { + case "" + }) + } + +} diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/Transformer2WConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/Transformer2WConverter.scala index c03b17f6..9e01cefe 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/Transformer2WConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/Transformer2WConverter.scala @@ -10,16 +10,56 @@ import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.connector.Transformer2WInput import edu.ie3.datamodel.models.input.connector.`type`.Transformer2WTypeInput +import edu.ie3.powerFactory2psdm.converter.NodeConverter.getNode +import edu.ie3.powerFactory2psdm.converter.types.Transformer2WTypeConverter.getTransformer2WType +import edu.ie3.powerFactory2psdm.exception.pf.ConversionException import edu.ie3.powerFactory2psdm.model.entity.Transformer2W - import java.util.UUID +import scala.util.{Failure, Success} object Transformer2WConverter extends LazyLogging { + def convertTransformers( + input: List[Transformer2W], + nodes: Map[String, NodeInput], + types: Map[String, Transformer2WTypeInput] + ): List[Transformer2WInput] = { + input map { transformer => + ( + getNode(transformer.nodeLvId, nodes), + getNode(transformer.nodeHvId, nodes), + getTransformer2WType(transformer.id, types) + ) match { + case (Success(nodeLv), Success(nodeHv), Success(transformer2WType)) => + Transformer2WConverter.convert( + transformer, + nodeHv, + nodeLv, + transformer2WType + ) + case (Failure(exc), _, _) => + throw ConversionException( + s"Could not find the converted lv node of 2W transformer: ${transformer.id}", + exc + ) + case (_, Failure(exc), _) => + throw ConversionException( + s"Could not find the converted hv node of 2W transformer: ${transformer.id}", + exc + ) + case (_, _, Failure(exc)) => + throw ConversionException( + s"Could not find the converted type of 2W transformer: ${transformer.id}", + exc + ) + } + } + } + def convert( input: Transformer2W, - nodeA: NodeInput, - nodeB: NodeInput, + nodeHv: NodeInput, + nodeLv: NodeInput, trafoType: Transformer2WTypeInput ): Transformer2WInput = { @@ -39,8 +79,8 @@ object Transformer2WConverter extends LazyLogging { new Transformer2WInput( UUID.randomUUID(), input.id, - nodeA, - nodeB, + nodeHv, + nodeLv, 1, trafoType, input.tapPos, diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/types/Transformer2WTypeConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/types/Transformer2WTypeConverter.scala index 09e53430..36559d22 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/types/Transformer2WTypeConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/types/Transformer2WTypeConverter.scala @@ -12,12 +12,10 @@ import edu.ie3.powerFactory2psdm.exception.pf.{ ElementConfigurationException } import edu.ie3.powerFactory2psdm.model.entity.types.Transformer2WType -import tech.units.indriya.quantity.Quantities -import tech.units.indriya.unit.Units.{OHM, PERCENT, SIEMENS, VOLT} -import edu.ie3.util.quantities.PowerSystemUnits.{DEGREE_GEOM, VOLTAMPERE} import edu.ie3.powerFactory2psdm.util.QuantityUtils.RichQuantityDouble import math.{pow, sqrt} import java.util.UUID +import scala.util.Try object Transformer2WTypeConverter { @@ -80,7 +78,10 @@ object Transformer2WTypeConverter { input.tapMin.toInt, input.tapMax.toInt ) - } + def getTransformer2WType( + id: String, + types: Map[String, Transformer2WTypeInput] + ): Try[Transformer2WTypeInput] = Try(types(id)) } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala index fff53de0..6279245c 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala @@ -6,11 +6,8 @@ package edu.ie3.powerFactory2psdm.model.entity -import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.{ - BasicDataSource, - LoadFlowSource, - ParameterSource -} +import edu.ie3.datamodel.models.input.system.{FixedFeedInInput, PvInput, WecInput} +import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.{BasicDataSource, LoadFlowSource, ParameterSource} import edu.ie3.powerFactory2psdm.exception.pf.MissingParameterException import edu.ie3.powerFactory2psdm.model.RawPfGridModel.StatGen @@ -100,3 +97,4 @@ object StaticGenerator { } } + From 7148821845ebecb5d614ebd1011d48ac2cb05ecc Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Mon, 25 Oct 2021 22:05:27 +0200 Subject: [PATCH 03/24] convert static generators --- .../config/model/DefaultModelConfig.scala | 10 +- .../config/model/PvConversionConfig.scala | 2 +- .../config/model/WecConversionConfig.scala | 2 +- .../converter/GridConverter.scala | 6 +- .../converter/LoadConverter.scala | 13 +- .../converter/NodeConverter.scala | 6 + .../converter/StaticGeneratorConverter.scala | 134 +++++++++++++++--- ...enerator.scala => WecInputGenerator.scala} | 2 +- .../model/entity/StaticGenerator.scala | 9 +- ...Spec.scala => WecInputGeneratorSpec.scala} | 8 +- 10 files changed, 155 insertions(+), 37 deletions(-) rename src/main/scala/edu/ie3/powerFactory2psdm/generator/{WecGenerator.scala => WecInputGenerator.scala} (98%) rename src/test/scala/edu/ie3/powerFactory2psdm/generator/{WecGeneratorSpec.scala => WecInputGeneratorSpec.scala} (84%) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala index a5a9b031..9af80020 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala @@ -10,17 +10,17 @@ import edu.ie3.powerFactory2psdm.config.model.IndividualModelConfig.ModelConvers /** Default model config to apply for the model conversion. */ -trait DefaultModelConfig { +trait DefaultModelConfig[T <: IndividualModelConfig] { val conversionMode: ModelConversionMode - val individualConfigs: Option[List[IndividualModelConfig]] -} + val individualConfigs: Option[List[T]] -object DefaultModelConfig { + def getIndividualModelConfig(modelId: String): Option[T] = + individualConfigs.flatMap(configs => configs.find(_.ids.contains(modelId))) /** Return conversion modes of the default and all individual model configs. */ def getConversionModes( - config: DefaultModelConfig + config: DefaultModelConfig[T] ): Seq[ModelConversionMode] = { Seq(config.conversionMode) ++ config.individualConfigs .getOrElse(Nil) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/PvConversionConfig.scala b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/PvConversionConfig.scala index 23e5896e..27893d35 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/PvConversionConfig.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/PvConversionConfig.scala @@ -29,7 +29,7 @@ import edu.ie3.powerFactory2psdm.generator.ParameterSamplingMethod final case class PvConversionConfig( conversionMode: PvModelConversionMode, individualConfigs: Option[List[IndividualPvConfig]] -) extends DefaultModelConfig +) extends DefaultModelConfig[IndividualPvConfig] {} object PvConversionConfig { diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/WecConversionConfig.scala b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/WecConversionConfig.scala index 5db53a4c..47e112f5 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/WecConversionConfig.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/WecConversionConfig.scala @@ -29,7 +29,7 @@ import edu.ie3.powerFactory2psdm.generator.ParameterSamplingMethod final case class WecConversionConfig( conversionMode: WecModelConversionMode, individualConfigs: Option[List[IndividualWecConfig]] -) extends DefaultModelConfig +) extends DefaultModelConfig[IndividualWecConfig] object WecConversionConfig { diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala index 9f582b82..5a313311 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala @@ -8,7 +8,10 @@ package edu.ie3.powerFactory2psdm.converter import edu.ie3.powerFactory2psdm.config.ConversionConfig import edu.ie3.powerFactory2psdm.config.ConversionConfig.StatGenModelConfigs -import edu.ie3.powerFactory2psdm.converter.types.{LineTypeConverter, Transformer2WTypeConverter} +import edu.ie3.powerFactory2psdm.converter.types.{ + LineTypeConverter, + Transformer2WTypeConverter +} import edu.ie3.powerFactory2psdm.model.{PreprocessedPfGridModel, RawPfGridModel} /** Functionalities to transform an exported and then parsed PowerFactory grid @@ -59,5 +62,6 @@ case object GridConverter { transformer2WTypes ) val loads = LoadConverter.convertLoads(grid.loads, nodes) + val statGenModels = ??? } } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala index e783e1b1..39a4cb75 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala @@ -21,13 +21,18 @@ import scala.util.{Failure, Success} object LoadConverter { - def convertLoads(input: List[Load], nodes: Map[String, NodeInput]): List[LoadInput] = { + def convertLoads( + input: List[Load], + nodes: Map[String, NodeInput] + ): List[LoadInput] = { input map { load => getNode(load.nodeId, nodes) match { case Success(node) => convert(load, node) - case Failure(exc) => throw ConversionException( - s"Could not convert load due to inability of finding its converted node with id: ${load.nodeId}", exc - ) + case Failure(exc) => + throw ConversionException( + s"Could not convert load due to inability of finding its converted node with id: ${load.nodeId}", + exc + ) } } } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/NodeConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/NodeConverter.scala index d2f8bfdc..c4c79f32 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/NodeConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/NodeConverter.scala @@ -113,4 +113,10 @@ object NodeConverter { ) ) } + + def missingNodeException( + system: String, + exc: Throwable + ): ConversionException = + ConversionException(s"Can't find converted node of $system", exc) } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala index acc48865..0d7d526a 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala @@ -1,28 +1,128 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + package edu.ie3.powerFactory2psdm.converter -import edu.ie3.datamodel.models.input.system.{FixedFeedInInput, PvInput, WecInput} +import com.typesafe.scalalogging.LazyLogging +import edu.ie3.datamodel.models.input.NodeInput +import edu.ie3.datamodel.models.input.system.{ + FixedFeedInInput, + PvInput, + WecInput +} import edu.ie3.powerFactory2psdm.config.ConversionConfig.StatGenModelConfigs +import edu.ie3.powerFactory2psdm.config.model.PvConversionConfig.{ + PvFixedFeedIn, + PvModelGeneration +} +import edu.ie3.powerFactory2psdm.config.model.WecConversionConfig.{ + WecFixedFeedIn, + WecModelGeneration +} +import edu.ie3.powerFactory2psdm.exception.pf.ConversionException +import edu.ie3.powerFactory2psdm.generator.{PvInputGenerator, WecInputGenerator} import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator +import scala.util.{Failure, Success} -object StaticGeneratorConverter { +object StaticGeneratorConverter extends LazyLogging { - /*** - * Container class to house the different PSDM models resulting from the conversion of the [[StaticGenerator]]s - * - * @param fixedFeedIns fixed feed ins - * @param pvInputs pv models - * @param wecInputs wec models - */ + /** * Container class to house the different PSDM models resulting from the + * conversion of the [[StaticGenerator]] s + * + * @param fixedFeedIns + * fixed feed ins + * @param pvInputs + * pv models + * @param wecInputs + * wec models + */ final case class StatGenModelContainer( - fixedFeedIns: List[FixedFeedInInput], - pvInputs: List[PvInput], - wecInputs: List[WecInput] - ) + fixedFeedIns: List[FixedFeedInInput], + pvInputs: List[PvInput], + wecInputs: List[WecInput] + ) + + def convert( + input: List[StaticGenerator], + conversionConfig: StatGenModelConfigs, + nodes: Map[String, NodeInput] + ): StatGenModelContainer = { + val emptyModelContainer + : (List[FixedFeedInInput], List[PvInput], List[WecInput]) = + (Nil, Nil, Nil) + val convertedModels = input.foldLeft(emptyModelContainer) { + case ((fixed, pv, wec), statGen) => + convert(statGen, conversionConfig, nodes) match { + case x: FixedFeedInInput => (x :: fixed, pv, wec) + case x: PvInput => (fixed, x :: pv, wec) + case x: WecInput => (fixed, pv, x :: wec) + case x => { + logger error s"Got an unexpected model: $x. This will be ignored and not converted!" + (fixed, pv, wec) + } + } + } + StatGenModelContainer( + convertedModels._1, + convertedModels._2, + convertedModels._3 + ) + } - def convert(input: List[StaticGenerator], conversionConfig: StatGenModelConfigs): StatGenModelContainer = { - input.map(statGen => statGen.category match { - case "" - }) + def convert( + statGen: StaticGenerator, + conversionConfig: StatGenModelConfigs, + nodes: Map[String, NodeInput] + ): Any = { + val node = NodeConverter.getNode(statGen.busId, nodes) match { + case Failure(exc) => + throw ConversionException( + s"Can't find converted node of static generator: ${statGen.busId}", + exc + ) + case Success(node) => node + } + statGen.category match { + case "Fotovoltaik" => { + val maybeIndividualConfig = + conversionConfig.pvConfig.getIndividualModelConfig(statGen.id) + val conversionMode = maybeIndividualConfig + .map(config => config.conversionMode) + .getOrElse(conversionConfig.pvConfig.conversionMode) + conversionMode match { + case fixedFeedIn: PvFixedFeedIn => + FixedFeedInConverter.convert( + statGen, + node, + fixedFeedIn.qCharacteristic + ) + case modelGeneration: PvModelGeneration => + PvInputGenerator.generate(statGen, node, modelGeneration) + } + } + case "Wind" => { + val maybeIndividualConfig = + conversionConfig.wecConfig.getIndividualModelConfig(statGen.id) + val conversionMode = maybeIndividualConfig + .map(config => config.conversionMode) + .getOrElse(conversionConfig.wecConfig.conversionMode) + conversionMode match { + case fixedFeedIn: WecFixedFeedIn => + FixedFeedInConverter.convert( + statGen, + node, + fixedFeedIn.qCharacteristic + ) + case modelGeneration: WecModelGeneration => + WecInputGenerator.generate(statGen, node, modelGeneration) + } + } + case other => + logger error s"Specific model generation for category: $other is currently not supported." + } } } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/generator/WecGenerator.scala b/src/main/scala/edu/ie3/powerFactory2psdm/generator/WecInputGenerator.scala similarity index 98% rename from src/main/scala/edu/ie3/powerFactory2psdm/generator/WecGenerator.scala rename to src/main/scala/edu/ie3/powerFactory2psdm/generator/WecInputGenerator.scala index 11f1ae60..d5ab251b 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/generator/WecGenerator.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/generator/WecInputGenerator.scala @@ -17,7 +17,7 @@ import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator import java.util.UUID -object WecGenerator { +object WecInputGenerator { /** Generates a [[WecInput]] and a [[WecTypeInput]] to replace a shallow * [[StaticGenerator]]. As a static generator does not hold all parameters diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala index 6279245c..6b3c20dc 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala @@ -6,8 +6,11 @@ package edu.ie3.powerFactory2psdm.model.entity -import edu.ie3.datamodel.models.input.system.{FixedFeedInInput, PvInput, WecInput} -import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.{BasicDataSource, LoadFlowSource, ParameterSource} +import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.{ + BasicDataSource, + LoadFlowSource, + ParameterSource +} import edu.ie3.powerFactory2psdm.exception.pf.MissingParameterException import edu.ie3.powerFactory2psdm.model.RawPfGridModel.StatGen @@ -92,9 +95,7 @@ object StaticGenerator { s"There is no category specifier defined for static generator: $id" ) ) - StaticGenerator(id, busId, sRated, cosPhi, indCapFlag, category) } } - diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/generator/WecGeneratorSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/generator/WecInputGeneratorSpec.scala similarity index 84% rename from src/test/scala/edu/ie3/powerFactory2psdm/generator/WecGeneratorSpec.scala rename to src/test/scala/edu/ie3/powerFactory2psdm/generator/WecInputGeneratorSpec.scala index d5d0b704..70fe3c2e 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/generator/WecGeneratorSpec.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/generator/WecInputGeneratorSpec.scala @@ -15,7 +15,7 @@ import edu.ie3.powerFactory2psdm.common.ConverterTestData.{ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike -class WecGeneratorSpec extends Matchers with AnyWordSpecLike { +class WecInputGeneratorSpec extends Matchers with AnyWordSpecLike { "A wec generator" should { val generationPair = getGenerateWecPair("someWec") @@ -25,7 +25,8 @@ class WecGeneratorSpec extends Matchers with AnyWordSpecLike { "generate a WecInput correctly" in { val expected = generationPair.resultModel - val actual = WecGenerator.generate(input, node, modelGenerationConfig)._1 + val actual = + WecInputGenerator.generate(input, node, modelGenerationConfig)._1 actual.getId shouldBe expected.getId actual.getNode shouldBe expected.getNode @@ -33,7 +34,8 @@ class WecGeneratorSpec extends Matchers with AnyWordSpecLike { "generate a WecTypeInput correctly" in { val expected = generationPair.resultType - val actual = WecGenerator.generate(input, node, modelGenerationConfig)._2 + val actual = + WecInputGenerator.generate(input, node, modelGenerationConfig)._2 actual.getsRated shouldBe expected.getsRated actual.getEtaConv shouldBe expected.getEtaConv From 5614c4089942e333b24c6864fdb7ec7e108ce143 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Tue, 26 Oct 2021 10:25:22 +0200 Subject: [PATCH 04/24] use psdm snapshot version --- build.gradle | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index f09f45c0..c3702bc9 100644 --- a/build.gradle +++ b/build.gradle @@ -51,9 +51,10 @@ dependencies { implementation group: 'org.scalameta', name: "scalafmt-dynamic_${scalaVersion}", version: '3.0.7' - implementation('com.github.ie3-institute:PowerSystemDataModel:2.0.1') { + /* PowerSystemDataModel */ + implementation ('com.github.ie3-institute:PowerSystemDataModel:2.1-SNAPSHOT') { + /* Exclude nested logging and ie3 related dependencies */ exclude group: 'org.slf4j', module: 'slf4j-api' - /* Exclude our own nested dependencies */ exclude group: 'com.github.ie3-institute' } From a53e6b7f5391e67cf064f5b4197ce4fee162a971 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Tue, 26 Oct 2021 10:26:05 +0200 Subject: [PATCH 05/24] extend config with io --- .../config/ConversionConfig.scala | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/config/ConversionConfig.scala b/src/main/scala/edu/ie3/powerFactory2psdm/config/ConversionConfig.scala index 83814a5f..bfec40e2 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/config/ConversionConfig.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/config/ConversionConfig.scala @@ -6,14 +6,21 @@ package edu.ie3.powerFactory2psdm.config -import edu.ie3.powerFactory2psdm.config.ConversionConfig.StatGenModelConfigs +import edu.ie3.powerFactory2psdm.config.ConversionConfig.{ + OutputConfig, + StatGenModelConfigs +} import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.ParameterSource import edu.ie3.powerFactory2psdm.config.model.{ PvConversionConfig, WecConversionConfig } -final case class ConversionConfig(modelConfigs: StatGenModelConfigs) +final case class ConversionConfig( + gridName: String, + modelConfigs: StatGenModelConfigs, + output: OutputConfig +) /** Config used for the grid conversion */ @@ -35,6 +42,18 @@ object ConversionConfig { cosPhiSource: ParameterSource ) + final case class OutputConfig( + targetFolder: String, + csvConfig: CsvConfig + ) + + final case class CsvConfig( + directoryHierarchy: Boolean = true, + fileEncoding: String = "UTF-8", + fileEnding: String = ".csv", + separator: String = ";" + ) + sealed trait GenerationMethod /** Use the given value fixed value From f99b0c2189cffc9108787a94c126aa75e3144bbd Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Tue, 26 Oct 2021 10:26:57 +0200 Subject: [PATCH 06/24] static generator conversion --- .../converter/StaticGeneratorConverter.scala | 24 +++++++++---- .../model/entity/StaticGenerator.scala | 34 ++++++++++++++++--- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala index 0d7d526a..907ca3fa 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala @@ -25,6 +25,14 @@ import edu.ie3.powerFactory2psdm.config.model.WecConversionConfig.{ import edu.ie3.powerFactory2psdm.exception.pf.ConversionException import edu.ie3.powerFactory2psdm.generator.{PvInputGenerator, WecInputGenerator} import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator +import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.{ + BATTERY, + BIOGAS, + OTHER, + PV, + WEC +} + import scala.util.{Failure, Success} object StaticGeneratorConverter extends LazyLogging { @@ -86,7 +94,7 @@ object StaticGeneratorConverter extends LazyLogging { case Success(node) => node } statGen.category match { - case "Fotovoltaik" => { + case PV => val maybeIndividualConfig = conversionConfig.pvConfig.getIndividualModelConfig(statGen.id) val conversionMode = maybeIndividualConfig @@ -102,8 +110,7 @@ object StaticGeneratorConverter extends LazyLogging { case modelGeneration: PvModelGeneration => PvInputGenerator.generate(statGen, node, modelGeneration) } - } - case "Wind" => { + case WEC => val maybeIndividualConfig = conversionConfig.wecConfig.getIndividualModelConfig(statGen.id) val conversionMode = maybeIndividualConfig @@ -119,9 +126,14 @@ object StaticGeneratorConverter extends LazyLogging { case modelGeneration: WecModelGeneration => WecInputGenerator.generate(statGen, node, modelGeneration) } - } - case other => - logger error s"Specific model generation for category: $other is currently not supported." + case BIOGAS => + logger error s"Specific model generation for category: $BIOGAS is currently not supported. Generator ${statGen.id} will not be converted." + + case BATTERY => + logger error s"Specific model generation for category: $BATTERY is currently not supported. Generator ${statGen.id} will not be converted." + + case OTHER => + logger error s"Specific model generation for category: $OTHER is currently not supported. Generator ${statGen.id} will not be converted." } } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala index 6b3c20dc..507d1264 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala @@ -6,6 +6,7 @@ package edu.ie3.powerFactory2psdm.model.entity +import com.typesafe.scalalogging.LazyLogging import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.{ BasicDataSource, LoadFlowSource, @@ -13,6 +14,9 @@ import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.{ } import edu.ie3.powerFactory2psdm.exception.pf.MissingParameterException import edu.ie3.powerFactory2psdm.model.RawPfGridModel.StatGen +import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories._ + +import scala.util.{Failure, Success, Try} /** A static generator * @@ -35,10 +39,28 @@ final case class StaticGenerator( sRated: Double, cosPhi: Double, indCapFlag: Int, - category: String + category: Value ) extends EntityModel -object StaticGenerator { +object StaticGenerator extends LazyLogging { + + object StatGenCategories extends Enumeration { + val PV: Value = Value("Fotovoltaik") + val WEC: Value = Value("Wind") + val BIOGAS: Value = Value("Biogas") + val BATTERY: Value = Value("Batterie") + val OTHER: Value = Value("Other") + + def getCategory(category: String): Value = { + Try(withName(category)) match { + case Failure(_) => { + logger debug s"The category $category is not explicitly handled. Will assign $OTHER instead." + OTHER + } + case Success(value) => value + } + } + } def build( input: StatGen, @@ -90,9 +112,11 @@ object StaticGenerator { ) ) .toInt - val category = input.cCategory.getOrElse( - throw MissingParameterException( - s"There is no category specifier defined for static generator: $id" + val category = getCategory( + input.cCategory.getOrElse( + throw MissingParameterException( + s"There is no category specifier defined for static generator: $id" + ) ) ) StaticGenerator(id, busId, sRated, cosPhi, indCapFlag, category) From 0bd570b684e57fcbc052f008d35a9f2c5d08bf42 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Tue, 26 Oct 2021 10:27:22 +0200 Subject: [PATCH 07/24] grid conversion and persistence --- .../converter/GridConverter.scala | 92 +++++++++++++++++-- .../main/RunConversion.scala | 25 +++++ src/test/resources/application.conf | 2 + 3 files changed, 112 insertions(+), 7 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala index 5a313311..fdbf47f1 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala @@ -6,6 +6,30 @@ package edu.ie3.powerFactory2psdm.converter +import edu.ie3.datamodel.graph.SubGridTopologyGraph +import edu.ie3.datamodel.models.input.{MeasurementUnitInput, NodeInput} +import edu.ie3.datamodel.models.input.connector.Transformer3WInput +import edu.ie3.datamodel.models.input.container.{ + GraphicElements, + JointGridContainer, + RawGridElements, + SystemParticipants +} +import edu.ie3.datamodel.models.input.graphics.{ + LineGraphicInput, + NodeGraphicInput +} +import edu.ie3.datamodel.models.input.system.{ + BmInput, + ChpInput, + EvInput, + EvcsInput, + FixedFeedInInput, + HpInput, + PvInput, + StorageInput, + WecInput +} import edu.ie3.powerFactory2psdm.config.ConversionConfig import edu.ie3.powerFactory2psdm.config.ConversionConfig.StatGenModelConfigs import edu.ie3.powerFactory2psdm.converter.types.{ @@ -14,18 +38,34 @@ import edu.ie3.powerFactory2psdm.converter.types.{ } import edu.ie3.powerFactory2psdm.model.{PreprocessedPfGridModel, RawPfGridModel} +import scala.jdk.CollectionConverters.SetHasAsJava + /** Functionalities to transform an exported and then parsed PowerFactory grid * to the PSDM. */ case object GridConverter { - def convert(pfGrid: RawPfGridModel, config: ConversionConfig) = { + def convert( + pfGrid: RawPfGridModel, + config: ConversionConfig + ): JointGridContainer = { val grid = PreprocessedPfGridModel.build( pfGrid, config.modelConfigs.sRatedSource, config.modelConfigs.cosPhiSource ) - val gridElements = convertGridElements(grid) + val (gridElements, convertedNodes) = convertGridElements(grid) + val participants = + convertParticipants(grid, convertedNodes, config.modelConfigs) + new JointGridContainer( + config.gridName, + gridElements, + participants, + new GraphicElements( + Set.empty[NodeGraphicInput].asJava, + Set.empty[LineGraphicInput].asJava + ) + ) } /** Converts the grid elements of the PowerFactory grid @@ -34,9 +74,8 @@ case object GridConverter { * the raw parsed PowerFactoryGrid */ def convertGridElements( - grid: PreprocessedPfGridModel, - statGenConversionConfig: StatGenModelConfigs - ): Unit = { + grid: PreprocessedPfGridModel + ): (RawGridElements, Map[String, NodeInput]) = { val graph = GridGraphBuilder.build(grid.nodes, grid.lines ++ grid.switches) val nodeId2node = grid.nodes.map(node => (node.id, node)).toMap @@ -61,7 +100,46 @@ case object GridConverter { nodes, transformer2WTypes ) - val loads = LoadConverter.convertLoads(grid.loads, nodes) - val statGenModels = ??? + val switches = + grid.switches.map(switch => SwitchConverter.convert(switch, nodes)) + + ( + new RawGridElements( + nodes.values.toSet.asJava, + lines.toSet.asJava, + transfomers2W.toSet.asJava, + Set.empty[Transformer3WInput].asJava, + switches.toSet.asJava, + Set.empty[MeasurementUnitInput].asJava + ), + nodes + ) + + } + + def convertParticipants( + grid: PreprocessedPfGridModel, + convertedNodes: Map[String, NodeInput], + statGenConversionConfig: StatGenModelConfigs + ): SystemParticipants = { + val loads = LoadConverter.convertLoads(grid.loads, convertedNodes) + val statGenModelContainer = StaticGeneratorConverter.convert( + grid.staticGenerators, + statGenConversionConfig, + convertedNodes + ) + new SystemParticipants( + Set.empty[BmInput].asJava, + Set.empty[ChpInput].asJava, + Set.empty[EvcsInput].asJava, + Set.empty[EvInput].asJava, + statGenModelContainer.fixedFeedIns.toSet.asJava, + Set.empty[HpInput].asJava, + loads.toSet.asJava, + statGenModelContainer.pvInputs.toSet.asJava, + Set.empty[StorageInput].asJava, + statGenModelContainer.wecInputs.toSet.asJava + ) + } } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala b/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala index a91e5f0e..20bc3e4d 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala @@ -7,6 +7,9 @@ package edu.ie3.powerFactory2psdm.main import com.typesafe.scalalogging.LazyLogging +import edu.ie3.datamodel.io.csv.DefaultDirectoryHierarchy +import edu.ie3.datamodel.io.naming.{DefaultDirectoryHierarchy, EntityPersistenceNamingStrategy, FileNamingStrategy} +import edu.ie3.datamodel.io.sink.CsvFileSink import edu.ie3.powerFactory2psdm.config.ConversionConfig import edu.ie3.powerFactory2psdm.config.validate.ConfigValidator import edu.ie3.powerFactory2psdm.converter.GridConverter @@ -37,6 +40,28 @@ object RunConversion extends LazyLogging { .getOrElse( throw GridParsingException("Parsing the Json grid file failed") ) + logger.info("Converting grid to PSDM") val psdmGrid = GridConverter.convert(pfGrid, config) + + val baseTargetDirectory = config.output.targetFolder + + val csvSink = if (config.output.csvConfig.directoryHierarchy) { + new CsvFileSink( + baseTargetDirectory, + new FileNamingStrategy( + new EntityPersistenceNamingStrategy(), + new DefaultDirectoryHierarchy(baseTargetDirectory, config.gridName) + ), + false, + config.output.csvConfig.separator + ) + } else { + new CsvFileSink( + baseTargetDirectory, + new FileNamingStrategy(), + false, + config.output.csvConfig.separator + ) + } } } diff --git a/src/test/resources/application.conf b/src/test/resources/application.conf index b9c9b78f..35ecc1d5 100644 --- a/src/test/resources/application.conf +++ b/src/test/resources/application.conf @@ -1,4 +1,5 @@ conversion-config { + grid-name = "Test Grid" model-configs { pv-config = ${default-pv-config} wec-config = ${default-wec-config} @@ -9,6 +10,7 @@ conversion-config { type = "load-flow-source" } } + output = } default-pv-config { From 16fea36efbef892c3b02857c898ffa1b551df47b Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Tue, 26 Oct 2021 10:29:30 +0200 Subject: [PATCH 08/24] persist jointGridContainer --- .../edu/ie3/powerFactory2psdm/main/RunConversion.scala | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala b/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala index 20bc3e4d..fcba49ef 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala @@ -8,7 +8,11 @@ package edu.ie3.powerFactory2psdm.main import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.io.csv.DefaultDirectoryHierarchy -import edu.ie3.datamodel.io.naming.{DefaultDirectoryHierarchy, EntityPersistenceNamingStrategy, FileNamingStrategy} +import edu.ie3.datamodel.io.naming.{ + DefaultDirectoryHierarchy, + EntityPersistenceNamingStrategy, + FileNamingStrategy +} import edu.ie3.datamodel.io.sink.CsvFileSink import edu.ie3.powerFactory2psdm.config.ConversionConfig import edu.ie3.powerFactory2psdm.config.validate.ConfigValidator @@ -41,7 +45,7 @@ object RunConversion extends LazyLogging { throw GridParsingException("Parsing the Json grid file failed") ) logger.info("Converting grid to PSDM") - val psdmGrid = GridConverter.convert(pfGrid, config) + val jointGridContainer = GridConverter.convert(pfGrid, config) val baseTargetDirectory = config.output.targetFolder @@ -63,5 +67,6 @@ object RunConversion extends LazyLogging { config.output.csvConfig.separator ) } + csvSink.persistJointGrid(jointGridContainer) } } From 86b77554c465156bcc83df763333c24d620c6ebf Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Tue, 26 Oct 2021 11:33:48 +0200 Subject: [PATCH 09/24] ignore converted grids --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 61661385..a92aa980 100644 --- a/.gitignore +++ b/.gitignore @@ -157,5 +157,8 @@ build # Ignore out folder out +# Ignore default folder for converted grids +convertedGrids + # Ignore grid json src/main/python/pfGridExport From 570de0d7512ed46f975d1584b2ce20c680a6c8a2 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Tue, 26 Oct 2021 11:34:37 +0200 Subject: [PATCH 10/24] fixes --- .../config/model/DefaultModelConfig.scala | 16 +++++++-------- .../config/model/IndividualModelConfig.scala | 4 ++-- .../config/model/PvConversionConfig.scala | 4 ++-- .../config/model/WecConversionConfig.scala | 4 ++-- .../config/validate/ConfigValidator.scala | 20 ++++++------------- .../converter/GridConverter.scala | 6 ++++-- .../converter/Transformer2WConverter.scala | 2 +- .../main/RunConversion.scala | 1 - .../model/RawPfGridModel.scala | 7 +++---- .../powerFactory2psdm/model/entity/Load.scala | 6 +++--- .../model/entity/StaticGenerator.scala | 5 +++-- .../model/entity/Transformer2W.scala | 4 +++- src/test/resources/application.conf | 7 ++++++- 13 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala index 9af80020..682818e0 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala @@ -10,19 +10,19 @@ import edu.ie3.powerFactory2psdm.config.model.IndividualModelConfig.ModelConvers /** Default model config to apply for the model conversion. */ -trait DefaultModelConfig[T <: IndividualModelConfig] { - val conversionMode: ModelConversionMode - val individualConfigs: Option[List[T]] +trait DefaultModelConfig[M <: ModelConversionMode, I <: IndividualModelConfig[ + M +]] { + val conversionMode: M + val individualConfigs: Option[List[I]] - def getIndividualModelConfig(modelId: String): Option[T] = + def getIndividualModelConfig(modelId: String): Option[I] = individualConfigs.flatMap(configs => configs.find(_.ids.contains(modelId))) /** Return conversion modes of the default and all individual model configs. */ - def getConversionModes( - config: DefaultModelConfig[T] - ): Seq[ModelConversionMode] = { - Seq(config.conversionMode) ++ config.individualConfigs + def getConversionModes: Seq[M] = { + Seq(conversionMode) ++ individualConfigs .getOrElse(Nil) .map(conf => conf.conversionMode) } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/IndividualModelConfig.scala b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/IndividualModelConfig.scala index a7617bd0..b1aef984 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/IndividualModelConfig.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/IndividualModelConfig.scala @@ -8,9 +8,9 @@ package edu.ie3.powerFactory2psdm.config.model import edu.ie3.powerFactory2psdm.config.model.IndividualModelConfig.ModelConversionMode -trait IndividualModelConfig { +trait IndividualModelConfig[M <: ModelConversionMode] { val ids: Set[String] - val conversionMode: ModelConversionMode + val conversionMode: M } object IndividualModelConfig { diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/PvConversionConfig.scala b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/PvConversionConfig.scala index 27893d35..7faf98e3 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/PvConversionConfig.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/PvConversionConfig.scala @@ -29,7 +29,7 @@ import edu.ie3.powerFactory2psdm.generator.ParameterSamplingMethod final case class PvConversionConfig( conversionMode: PvModelConversionMode, individualConfigs: Option[List[IndividualPvConfig]] -) extends DefaultModelConfig[IndividualPvConfig] {} +) extends DefaultModelConfig[PvModelConversionMode, IndividualPvConfig] {} object PvConversionConfig { @@ -44,7 +44,7 @@ object PvConversionConfig { final case class IndividualPvConfig( ids: Set[String], conversionMode: PvModelConversionMode - ) extends IndividualModelConfig + ) extends IndividualModelConfig[PvModelConversionMode] /** Trait to denote modes for converting pv static generators */ diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/WecConversionConfig.scala b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/WecConversionConfig.scala index 47e112f5..bf5523e3 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/WecConversionConfig.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/WecConversionConfig.scala @@ -29,7 +29,7 @@ import edu.ie3.powerFactory2psdm.generator.ParameterSamplingMethod final case class WecConversionConfig( conversionMode: WecModelConversionMode, individualConfigs: Option[List[IndividualWecConfig]] -) extends DefaultModelConfig[IndividualWecConfig] +) extends DefaultModelConfig[WecModelConversionMode, IndividualWecConfig] object WecConversionConfig { @@ -44,7 +44,7 @@ object WecConversionConfig { final case class IndividualWecConfig( ids: Set[String], conversionMode: WecModelConversionMode - ) extends IndividualModelConfig + ) extends IndividualModelConfig[WecModelConversionMode] /** Trait to group different methods for generating a value for a model * parameter diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/config/validate/ConfigValidator.scala b/src/main/scala/edu/ie3/powerFactory2psdm/config/validate/ConfigValidator.scala index b0c60d5b..de99fc7f 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/config/validate/ConfigValidator.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/config/validate/ConfigValidator.scala @@ -18,10 +18,6 @@ import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.{ FixedQCharacteristic, QCharacteristic } -import edu.ie3.powerFactory2psdm.config.model.DefaultModelConfig.getConversionModes -import edu.ie3.powerFactory2psdm.config.model.PvConversionConfig.PvModelConversionMode -import edu.ie3.powerFactory2psdm.config.model.WecConversionConfig.WecModelConversionMode -import edu.ie3.powerFactory2psdm.config.validate.conversion.ConversionModeValidator import edu.ie3.powerFactory2psdm.exception.io.ConversionConfigException import edu.ie3.powerFactory2psdm.generator.ParameterSamplingMethod import edu.ie3.powerFactory2psdm.generator.ParameterSamplingMethod.{ @@ -47,16 +43,12 @@ object ConfigValidator extends LazyLogging { private[config] def validateModelConfigs( modelConfigs: StatGenModelConfigs ): Unit = { - Seq(modelConfigs.pvConfig, modelConfigs.wecConfig) - .flatMap(getConversionModes) - .foreach { - case x: PvModelConversionMode => PvConversionModeValidator.validate(x) - case x: WecModelConversionMode => WecConversionModeValidator.validate(x) - case conversionMode => - logger.warn( - s"The conversion mode $conversionMode is currently not validated." - ) - } + modelConfigs.pvConfig.getConversionModes.foreach( + PvConversionModeValidator.validate + ) + modelConfigs.wecConfig.getConversionModes.foreach( + WecConversionModeValidator.validate + ) } private[config] def validateParameterSamplingMethod( diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala index fdbf47f1..485c0ca3 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala @@ -91,8 +91,10 @@ case object GridConverter { lineTypes ) val transformer2WTypes = grid.transformerTypes2W - .map(transformer => - transformer.id -> Transformer2WTypeConverter.convert(transformer) + .map(transformerType => + transformerType.id -> Transformer2WTypeConverter.convert( + transformerType + ) ) .toMap val transfomers2W = Transformer2WConverter.convertTransformers( diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/Transformer2WConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/Transformer2WConverter.scala index 9e01cefe..56a0610b 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/Transformer2WConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/Transformer2WConverter.scala @@ -28,7 +28,7 @@ object Transformer2WConverter extends LazyLogging { ( getNode(transformer.nodeLvId, nodes), getNode(transformer.nodeHvId, nodes), - getTransformer2WType(transformer.id, types) + getTransformer2WType(transformer.typeId, types) ) match { case (Success(nodeLv), Success(nodeHv), Success(transformer2WType)) => Transformer2WConverter.convert( diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala b/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala index fcba49ef..e31777a4 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/main/RunConversion.scala @@ -7,7 +7,6 @@ package edu.ie3.powerFactory2psdm.main import com.typesafe.scalalogging.LazyLogging -import edu.ie3.datamodel.io.csv.DefaultDirectoryHierarchy import edu.ie3.datamodel.io.naming.{ DefaultDirectoryHierarchy, EntityPersistenceNamingStrategy, diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala index 92232b39..9add6b6a 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala @@ -5,7 +5,6 @@ */ package edu.ie3.powerFactory2psdm.model - import edu.ie3.powerFactory2psdm.model.RawPfGridModel.{ ExtGrid, PowerPlants, @@ -58,8 +57,8 @@ object RawPfGridModel { final case class ConElms(id: Option[String], pfCls: Option[String]) final case class Loads( - bus1Id: Option[String], pf_recap: Option[Double], + busId: Option[String], id: Option[String], coslini: Option[Double], slini: Option[Double] @@ -125,8 +124,8 @@ object RawPfGridModel { ) final case class LoadsLV( - bus1Id: Option[String], pf_recap: Option[Double], + busId: Option[String], id: Option[String], coslini: Option[Double], slini: Option[Double] @@ -154,8 +153,8 @@ object RawPfGridModel { final case class TrafoTypes3w() final case class LoadsMV( - bus1Id: Option[String], pf_recap: Option[Double], + busId: Option[String], id: Option[String], coslini: Option[Double], slini: Option[Double] diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/Load.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/Load.scala index 1d632290..189733d5 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/Load.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/Load.scala @@ -33,7 +33,7 @@ object Load { val id = input.id.getOrElse( throw MissingParameterException(s"Load $input has no defined id.") ) - val nodeId = input.bus1Id.getOrElse( + val nodeId = input.busId.getOrElse( throw MissingParameterException(s"Load $id has no defined bus") ) val s = input.slini.getOrElse( @@ -56,7 +56,7 @@ object Load { val id = input.id.getOrElse( throw MissingParameterException(s"LV Load $input has no defined id.") ) - val nodeId = input.bus1Id.getOrElse( + val nodeId = input.busId.getOrElse( throw MissingParameterException(s"LV Load $id has no defined bus") ) val s = input.slini.getOrElse( @@ -81,7 +81,7 @@ object Load { val id = input.id.getOrElse( throw MissingParameterException(s"MV Load $input has no defined id.") ) - val nodeId = input.bus1Id.getOrElse( + val nodeId = input.busId.getOrElse( throw MissingParameterException(s"MV Load $id has no defined bus") ) val s = input.slini.getOrElse( diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala index 507d1264..9e14d288 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala @@ -14,7 +14,8 @@ import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.{ } import edu.ie3.powerFactory2psdm.exception.pf.MissingParameterException import edu.ie3.powerFactory2psdm.model.RawPfGridModel.StatGen -import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories._ +import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories +import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.getCategory import scala.util.{Failure, Success, Try} @@ -39,7 +40,7 @@ final case class StaticGenerator( sRated: Double, cosPhi: Double, indCapFlag: Int, - category: Value + category: StatGenCategories.Value ) extends EntityModel object StaticGenerator extends LazyLogging { diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2W.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2W.scala index 81eb568d..c59ac294 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2W.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2W.scala @@ -49,7 +49,9 @@ object Transformer2W { throw MissingParameterException(s"Trafo2w: $id has no lv bus id.") ) val typeId = rawTrafo.typeId.getOrElse( - throw MissingParameterException(s"Trafo2w: $id has no type id.") + throw MissingParameterException( + s"Trafo2w: $id has no type. Transformer conversion without specified types is not supported." + ) ) val tapPos = rawTrafo.nntap .getOrElse( diff --git a/src/test/resources/application.conf b/src/test/resources/application.conf index 35ecc1d5..38199d6b 100644 --- a/src/test/resources/application.conf +++ b/src/test/resources/application.conf @@ -10,7 +10,7 @@ conversion-config { type = "load-flow-source" } } - output = + output = ${default-output-config} } default-pv-config { @@ -77,4 +77,9 @@ default-wec-config { value = 95 } } +} + +default-output-config { + target-folder = ./convertedGrids + csv-config = {} } \ No newline at end of file From a17181c4bfdea3de87c7e5c95bffe22dd9459a8c Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Wed, 27 Oct 2021 16:58:49 +0200 Subject: [PATCH 11/24] add grid converter test --- .../converter/GridConverter.scala | 12 +- .../converter/StaticGeneratorConverter.scala | 12 +- .../model/entity/StaticGenerator.scala | 5 +- src/test/resources/pfGrids/exampleGrid.json | 109 +++++++++++++++--- .../common/ConverterTestData.scala | 34 ++++-- .../converter/GridConverterSpec.scala | 46 ++++++++ .../converter/GridGraphBuilderSpec.scala | 10 +- .../converter/SubnetBuilderSpec.scala | 6 +- .../model/entity/LoadSpec.scala | 12 +- 9 files changed, 187 insertions(+), 59 deletions(-) create mode 100644 src/test/scala/edu/ie3/powerFactory2psdm/converter/GridConverterSpec.scala diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala index 485c0ca3..13a4e554 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala @@ -6,7 +6,6 @@ package edu.ie3.powerFactory2psdm.converter -import edu.ie3.datamodel.graph.SubGridTopologyGraph import edu.ie3.datamodel.models.input.{MeasurementUnitInput, NodeInput} import edu.ie3.datamodel.models.input.connector.Transformer3WInput import edu.ie3.datamodel.models.input.container.{ @@ -24,11 +23,8 @@ import edu.ie3.datamodel.models.input.system.{ ChpInput, EvInput, EvcsInput, - FixedFeedInInput, HpInput, - PvInput, - StorageInput, - WecInput + StorageInput } import edu.ie3.powerFactory2psdm.config.ConversionConfig import edu.ie3.powerFactory2psdm.config.ConversionConfig.StatGenModelConfigs @@ -119,6 +115,12 @@ case object GridConverter { } + /** Convert system participants to PSDM + * @param grid + * @param convertedNodes + * @param statGenConversionConfig + * @return + */ def convertParticipants( grid: PreprocessedPfGridModel, convertedNodes: Map[String, NodeInput], diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala index 907ca3fa..45d7f44b 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala @@ -26,8 +26,6 @@ import edu.ie3.powerFactory2psdm.exception.pf.ConversionException import edu.ie3.powerFactory2psdm.generator.{PvInputGenerator, WecInputGenerator} import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.{ - BATTERY, - BIOGAS, OTHER, PV, WEC @@ -67,6 +65,7 @@ object StaticGeneratorConverter extends LazyLogging { case x: FixedFeedInInput => (x :: fixed, pv, wec) case x: PvInput => (fixed, x :: pv, wec) case x: WecInput => (fixed, pv, x :: wec) + case () => (fixed, pv, wec) case x => { logger error s"Got an unexpected model: $x. This will be ignored and not converted!" (fixed, pv, wec) @@ -126,14 +125,9 @@ object StaticGeneratorConverter extends LazyLogging { case modelGeneration: WecModelGeneration => WecInputGenerator.generate(statGen, node, modelGeneration) } - case BIOGAS => - logger error s"Specific model generation for category: $BIOGAS is currently not supported. Generator ${statGen.id} will not be converted." - - case BATTERY => - logger error s"Specific model generation for category: $BATTERY is currently not supported. Generator ${statGen.id} will not be converted." - case OTHER => - logger error s"Specific model generation for category: $OTHER is currently not supported. Generator ${statGen.id} will not be converted." + logger error s"Generator: ${statGen.id} will not be converted as its category is marked as $OTHER. " + + s"For supported categories check class [[StatGenCategories]]" } } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala index 9e14d288..d7a01eb7 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/entity/StaticGenerator.scala @@ -48,14 +48,13 @@ object StaticGenerator extends LazyLogging { object StatGenCategories extends Enumeration { val PV: Value = Value("Fotovoltaik") val WEC: Value = Value("Wind") - val BIOGAS: Value = Value("Biogas") - val BATTERY: Value = Value("Batterie") val OTHER: Value = Value("Other") def getCategory(category: String): Value = { Try(withName(category)) match { case Failure(_) => { - logger debug s"The category $category is not explicitly handled. Will assign $OTHER instead." + logger debug s"The category $category is not explicitly handled. Will assign $OTHER instead. NOTE: These generators " + + s"will not be converted. " OTHER } case Success(value) => value diff --git a/src/test/resources/pfGrids/exampleGrid.json b/src/test/resources/pfGrids/exampleGrid.json index f65d7873..2f9a7608 100644 --- a/src/test/resources/pfGrids/exampleGrid.json +++ b/src/test/resources/pfGrids/exampleGrid.json @@ -33,6 +33,14 @@ { "id": "Grid.ElmNet\\Externes Netz.ElmXnet", "pfCls": "ElmXnet" + }, + { + "id": "Grid.ElmNet\\Niederspannungslast(1).ElmLodlv", + "pfCls": "ElmLodlv" + }, + { + "id": "Grid.ElmNet\\Mittelspannungslast.ElmLodmv", + "pfCls": "ElmLodmv" } ] }, @@ -413,13 +421,13 @@ "uknom": 33.0, "vtarget": 1.0, "conElms": [ - { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\2-Wicklungstransformator.ElmTr2", - "pfCls": "ElmTr2" - }, { "id": "Grid.ElmNet\\LS/TR Schalter(1).ElmCoup", "pfCls": "ElmCoup" + }, + { + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\2-Wicklungstransformator.ElmTr2", + "pfCls": "ElmTr2" } ] }, @@ -431,38 +439,38 @@ "vtarget": 1.0, "conElms": [ { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S1.ElmCoup", + "id": "Grid.ElmNet\\LS/TR Schalter(1).ElmCoup", "pfCls": "ElmCoup" }, { - "id": "Grid.ElmNet\\LS/TR Schalter(1).ElmCoup", + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S1.ElmCoup", "pfCls": "ElmCoup" } ] }, { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\2.ElmTerm", + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\ON_Station_Upper.ElmTerm", "GPSlat": 0.0, "GPSlon": 0.0, - "uknom": 33.0, + "uknom": 110.0, "vtarget": 1.0, "conElms": [ { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S2.ElmCoup", - "pfCls": "ElmCoup" + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\2-Wicklungstransformator.ElmTr2", + "pfCls": "ElmTr2" } ] }, { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\ON_Station_Upper.ElmTerm", + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\2.ElmTerm", "GPSlat": 0.0, "GPSlon": 0.0, - "uknom": 110.0, + "uknom": 33.0, "vtarget": 1.0, "conElms": [ { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\2-Wicklungstransformator.ElmTr2", - "pfCls": "ElmTr2" + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S2.ElmCoup", + "pfCls": "ElmCoup" } ] } @@ -865,7 +873,7 @@ "busHvId": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\ON_Station_Upper.ElmTerm", "busLvId": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\ON_Station_Lower.ElmTerm", "cPtapc": null, - "typeId": null + "typeId": "\\Lib.IntLibrary\\Types\\Transf\\Tr2\\50Hz\\Dis\\10kV\\0.01 MVA 10/0.4 kV DT 10 SGB.TypTr2" }, { "id": "Grid.ElmNet\\Trf_0005_0006.ElmTr2", @@ -942,6 +950,22 @@ "utrn_h": 33.0, "utrn_l": 1.0 }, + { + "id": "\\Lib.IntLibrary\\Types\\Transf\\Tr2\\50Hz\\Dis\\10kV\\0.01 MVA 10/0.4 kV DT 10 SGB.TypTr2", + "curmg": 1.2000099420547485, + "dutap": 2.5, + "nntap0": 0, + "ntpmn": -2, + "ntpmx": 2, + "pcutr": 0.3499999940395355, + "pfe": 0.11999999731779099, + "phitr": 0.0, + "strn": 0.009999999776482582, + "tap_side": 0, + "uktr": 4.0, + "utrn_h": 10.0, + "utrn_l": 0.4000000059604645 + }, { "id": "TypTr2 0005 to 0006.TypTr2", "curmg": 0.0, @@ -964,65 +988,118 @@ "loads": [ { "id": "Grid.ElmNet\\Load_0011.ElmLod", + "coslini": 0.8892877697944641, + "pf_recap": 0, + "slini": 3.9357337951660156e+24, "busId": "Grid.ElmNet\\Bus_0011.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0012.ElmLod", + "coslini": 0.9672796130180359, + "pf_recap": 0, + "slini": 6.30634593963623e+24, "busId": "Grid.ElmNet\\Bus_0012.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0013.ElmLod", + "coslini": 0.9187926650047302, + "pf_recap": 0, + "slini": 1.4693195343017578e+25, "busId": "Grid.ElmNet\\Bus_0013.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0014.ElmLod", + "coslini": 0.9480450749397278, + "pf_recap": 0, + "slini": 1.5716551780700683e+25, "busId": "Grid.ElmNet\\Bus_0014.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0002.ElmLod", + "coslini": 0.8630567789077759, + "pf_recap": 0, + "slini": 2.514319038391113e+25, "busId": "Grid.ElmNet\\Bus_0002.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0003.ElmLod", + "coslini": 0.9802591800689697, + "pf_recap": 0, + "slini": 9.609703063964843e+25, "busId": "Grid.ElmNet\\Bus_0003.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0004.ElmLod", + "coslini": 0.9966880679130554, + "pf_recap": 1, + "slini": 4.795883560180664e+25, "busId": "Grid.ElmNet\\Bus_0004.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0005.ElmLod", + "coslini": 0.9785497784614563, + "pf_recap": 0, + "slini": 7.766594886779785e+24, "busId": "Grid.ElmNet\\Bus_0005.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0006.ElmLod", + "coslini": 0.8309071660041809, + "pf_recap": 0, + "slini": 1.3479243278503417e+25, "busId": "Grid.ElmNet\\Bus_0006.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0015.ElmLod", + "coslini": 0.9480450749397278, + "pf_recap": 0, + "slini": 1.5716551780700683e+25, "busId": "Grid.ElmNet\\Bus_0015.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0010.ElmLod", + "coslini": 0.8405709862709045, + "pf_recap": 0, + "slini": 1.070700740814209e+25, "busId": "Grid.ElmNet\\Bus_0010.ElmTerm" } ], "loadsLV": [ { "id": "Grid.ElmNet\\Niederspannungslast.ElmLodlv", + "coslini": 0.9700000286102295, + "pf_recap": 0, + "slini": 1.0, "busId": "Grid.ElmNet\\Bus_0007.ElmTerm" + }, + { + "id": "Grid.ElmNet\\Niederspannungslast(1).ElmLodlv", + "coslini": 1.0, + "pf_recap": 0, + "slini": 0.0, + "busId": "Grid.ElmNet\\Bus_0001.ElmTerm" } ], "loadsMV": [ { "id": "Grid.ElmNet\\Load_0009.ElmLodmv", + "coslini": 0.8999999761581421, + "pf_recap": 0, + "slini": 3.2777778625488283e+25, "busId": "Grid.ElmNet\\Bus_0009.ElmTerm" + }, + { + "id": "Grid.ElmNet\\Mittelspannungslast.ElmLodmv", + "coslini": 1.0, + "pf_recap": 0, + "slini": 0.0, + "busId": "Grid.ElmNet\\Bus_0001.ElmTerm" } ], "statGen": [ { "id": "Grid.ElmNet\\Statischer Generator.ElmGenstat", - "cCategory": "Statischer Generator", + "cCategory": "Fotovoltaik", "cosgini": 1.0, "cosn": 0.800000011920929, "pf_recap": 0, diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/common/ConverterTestData.scala b/src/test/scala/edu/ie3/powerFactory2psdm/common/ConverterTestData.scala index ac940b6e..2de4253a 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/common/ConverterTestData.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/common/ConverterTestData.scala @@ -66,11 +66,17 @@ import edu.ie3.powerFactory2psdm.model.entity.{ Subnet } import edu.ie3.powerFactory2psdm.model.entity.types.LineType -import edu.ie3.powerFactory2psdm.model.PreprocessedPfGridModel +import edu.ie3.powerFactory2psdm.model.{PreprocessedPfGridModel, RawPfGridModel} import org.locationtech.jts.geom.{Coordinate, GeometryFactory} import pureconfig.ConfigSource import pureconfig.generic.auto._ import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils.MV_10KV +import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.{ + OTHER, + PV, + WEC +} + import java.io.File import java.util.{Locale, UUID} @@ -127,20 +133,24 @@ object ConverterTestData extends LazyLogging { val testGridFile = s"${new File(".").getCanonicalPath}/src/test/resources/pfGrids/exampleGrid.json" - val testGrid: PreprocessedPfGridModel = PreprocessedPfGridModel.build( - PfGridParser - .parse(testGridFile) - .getOrElse( - throw GridParsingException( - s"Couldn't parse the grid file $testGridFile" - ) + val rawGrid: RawPfGridModel = PfGridParser + .parse(testGridFile) + .getOrElse( + throw GridParsingException( + s"Couldn't parse the grid file $testGridFile" ) + ) + + val preProcessedGrid: PreprocessedPfGridModel = PreprocessedPfGridModel.build( + rawGrid, + config.modelConfigs.sRatedSource, + config.modelConfigs.cosPhiSource ) logger.info("Sucessfully built the grid model") val id2node: Map[String, Node] = - testGrid.nodes.map(node => (node.id, node)).toMap + preProcessedGrid.nodes.map(node => (node.id, node)).toMap val bus1Id = "Grid.ElmNet\\Bus_0001.ElmTerm" val bus2Id = "Grid.ElmNet\\Bus_0002.ElmTerm" @@ -335,7 +345,7 @@ object ConverterTestData extends LazyLogging { sRated = 11, cosPhi = 0.91, indCapFlag = 0, - category = "Statischer Generator" + category = OTHER ) val statGenCosPhiExcMsg: String => String = (id: String) => @@ -353,7 +363,7 @@ object ConverterTestData extends LazyLogging { val generatePvs: Map[String, ConversionPair[StaticGenerator, PvInput]] = Map( "somePvPlant" -> ConversionPair( - staticGenerator.copy(category = "Fotovoltaik"), + staticGenerator.copy(category = PV), new PvInput( UUID.randomUUID(), "someStatGen", @@ -446,7 +456,7 @@ object ConverterTestData extends LazyLogging { WecTypeInput ]] = Map( "someWec" -> ConversionPairWithType( - staticGenerator.copy(id = "someWec", category = "Wind"), + staticGenerator.copy(id = "someWec", category = WEC), new WecInput( UUID.randomUUID(), "someWec", diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridConverterSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridConverterSpec.scala new file mode 100644 index 00000000..bd2de890 --- /dev/null +++ b/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridConverterSpec.scala @@ -0,0 +1,46 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.powerFactory2psdm.converter + +import edu.ie3.powerFactory2psdm.common.ConverterTestData +import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.{ + PV, + WEC +} +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpecLike + +class GridConverterSpec extends Matchers with AnyWordSpecLike { + + "A grid converter" should { + val config = ConverterTestData.config + val rawGrid = ConverterTestData.rawGrid + val preProcessedGrid = ConverterTestData.preProcessedGrid + val result = GridConverter.convert(rawGrid, config) + + "convert all grid elements" in { + val gridElements = result.getRawGrid + gridElements.getNodes.size shouldBe preProcessedGrid.nodes.size + gridElements.getLines.size shouldBe preProcessedGrid.lines.size + gridElements.getSwitches.size shouldBe preProcessedGrid.switches.size + gridElements.getTransformer2Ws.size shouldBe preProcessedGrid.transformers2W.size + } + + "convert all system participants" in { + result.getSystemParticipants.getLoads.size shouldBe preProcessedGrid.loads.size + val expectedPvs = preProcessedGrid.staticGenerators.count(statgen => + statgen.category == PV + ) + result.getSystemParticipants.getPvPlants.size shouldBe expectedPvs + val expectedWecs = preProcessedGrid.staticGenerators.count(statgen => + statgen.category == WEC + ) + result.getSystemParticipants.getWecPlants.size shouldBe expectedWecs + + } + } +} diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridGraphBuilderSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridGraphBuilderSpec.scala index 748b9758..672301c1 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridGraphBuilderSpec.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridGraphBuilderSpec.scala @@ -11,7 +11,7 @@ import edu.ie3.powerFactory2psdm.common.ConverterTestData.{ subnet2Ids, subnet3Ids, subnet4Ids, - testGrid + preProcessedGrid } import edu.ie3.powerFactory2psdm.exception.pf.ElementConfigurationException import org.jgrapht.alg.connectivity.BiconnectivityInspector @@ -25,21 +25,21 @@ class GridGraphBuilderSpec extends Matchers with AnyWordSpecLike { "The GridGraphBuilder" should { val gridGraph = GridGraphBuilder.build( - testGrid.nodes, - testGrid.lines ++ testGrid.switches + preProcessedGrid.nodes, + preProcessedGrid.lines ++ preProcessedGrid.switches ) val inspect = new BiconnectivityInspector(gridGraph) val vertexSets = inspect.getConnectedComponents.asScala .map(graph => graph.vertexSet()) "add the correct number of nodes to the gridGraph" in { - gridGraph.vertexSet().size shouldBe testGrid.nodes.size + gridGraph.vertexSet().size shouldBe preProcessedGrid.nodes.size } "add the correct number of edges to the gridGraph" in { gridGraph .edgeSet() - .size shouldBe (testGrid.lines ++ testGrid.switches).size + .size shouldBe (preProcessedGrid.lines ++ preProcessedGrid.switches).size } "generate the correct number of subnets" in { diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/converter/SubnetBuilderSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/converter/SubnetBuilderSpec.scala index 4a2f53f2..7ae3a5c2 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/converter/SubnetBuilderSpec.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/converter/SubnetBuilderSpec.scala @@ -10,7 +10,7 @@ import edu.ie3.powerFactory2psdm.common.ConverterTestData.{ id2node, subnet1Ids, subnet2Ids, - testGrid + preProcessedGrid } import edu.ie3.powerFactory2psdm.exception.pf.{ ElementConfigurationException, @@ -26,8 +26,8 @@ class SubnetBuilderSpec extends Matchers with AnyWordSpecLike { "The SubnetBuilder" should { val gridGraph = GridGraphBuilder.build( - testGrid.nodes, - testGrid.lines ++ testGrid.switches + preProcessedGrid.nodes, + preProcessedGrid.lines ++ preProcessedGrid.switches ) val subgraphs = new BiconnectivityInspector(gridGraph).getConnectedComponents diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/LoadSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/LoadSpec.scala index 16560722..bdfb19a3 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/LoadSpec.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/LoadSpec.scala @@ -19,7 +19,7 @@ class LoadSpec extends Matchers with AnyWordSpecLike { val id = "someLoad" val input = Loads( id = Some(id), - bus1Id = Some("someNode"), + busId = Some("someNode"), pf_recap = Some(0d), coslini = Some(0.841241), slini = Some(10.2432) @@ -32,7 +32,7 @@ class LoadSpec extends Matchers with AnyWordSpecLike { } "throw an exception building a node if the node id is missing" in { - val faulty = input.copy(bus1Id = None) + val faulty = input.copy(busId = None) val exc = intercept[MissingParameterException](Load.build(faulty)) exc.getMessage shouldBe s"Load $id has no defined bus" } @@ -72,7 +72,7 @@ class LoadSpec extends Matchers with AnyWordSpecLike { val id = "someLoad" val input = LoadsLV( id = Some(id), - bus1Id = Some("someNode"), + busId = Some("someNode"), pf_recap = Some(0d), coslini = Some(0.841241), slini = Some(10.2432) @@ -85,7 +85,7 @@ class LoadSpec extends Matchers with AnyWordSpecLike { } "throw an exception building a node if the node id is missing" in { - val faulty = input.copy(bus1Id = None) + val faulty = input.copy(busId = None) val exc = intercept[MissingParameterException](Load.build(faulty)) exc.getMessage shouldBe s"LV Load $id has no defined bus" } @@ -124,7 +124,7 @@ class LoadSpec extends Matchers with AnyWordSpecLike { val id = "someLoad" val input = LoadsMV( id = Some(id), - bus1Id = Some("someNode"), + busId = Some("someNode"), pf_recap = Some(0d), coslini = Some(0.841241), slini = Some(10.2432) @@ -137,7 +137,7 @@ class LoadSpec extends Matchers with AnyWordSpecLike { } "throw an exception building a node if the node id is missing" in { - val faulty = input.copy(bus1Id = None) + val faulty = input.copy(busId = None) val exc = intercept[MissingParameterException](Load.build(faulty)) exc.getMessage shouldBe s"MV Load $id has no defined bus" } From 8e9b33c14e0c53d1c6ed31ed9ab5ab3aa2783b3a Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Wed, 27 Oct 2021 17:02:42 +0200 Subject: [PATCH 12/24] add some docs --- .../edu/ie3/powerFactory2psdm/converter/GridConverter.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala index 13a4e554..ad739753 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/GridConverter.scala @@ -115,10 +115,14 @@ case object GridConverter { } - /** Convert system participants to PSDM + /** Convert system participants of the power factory grid. + * * @param grid + * the PF grid * @param convertedNodes + * the converted nodes * @param statGenConversionConfig + * the conversion configuration for static generators * @return */ def convertParticipants( From b87abff5965b7c13ee6bff1a16e9b8e4c3d3ae85 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Thu, 28 Oct 2021 13:02:50 +0200 Subject: [PATCH 13/24] avoid exceptions in converter test data --- .../converter/LoadConverter.scala | 5 +- .../model/PreprocessedPfGridModel.scala | 4 +- src/test/resources/pfGrids/exampleGrid.json | 50 +++++++++++++++---- .../common/ConverterTestData.scala | 46 ++++++++++------- .../converter/GridConverterSpec.scala | 4 +- .../converter/GridGraphBuilderSpec.scala | 19 ++++--- .../converter/SubnetBuilderSpec.scala | 13 +++-- .../model/entity/Transformer2WSpec.scala | 2 +- 8 files changed, 94 insertions(+), 49 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala index 60ded851..a2a6c53b 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/LoadConverter.scala @@ -10,10 +10,7 @@ import edu.ie3.datamodel.models.{BdewLoadProfile, OperationTime} import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed -import edu.ie3.powerFactory2psdm.exception.pf.{ - ConversionException, - ElementConfigurationException -} +import edu.ie3.powerFactory2psdm.exception.pf.ElementConfigurationException import edu.ie3.powerFactory2psdm.converter.NodeConverter.getNode import edu.ie3.powerFactory2psdm.exception.pf.ConversionException import edu.ie3.powerFactory2psdm.model.entity.Load diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala index 7b5c4602..05bdd999 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala @@ -201,9 +201,9 @@ object PreprocessedPfGridModel extends LazyLogging { val transformers2W = rawTrafos2W.map(Transformer2W.build) val trafoTypes2W = rawTrafoTpyes2W.map(Transformer2WType.build) val loads = rawLoads.map { - case load: Loads => Load.build(load) + case load: Loads => Load.build(load, conversionPrefixes.loadPQSPrefix()) case load: LoadsLV => Load.build(load) - case load: LoadsMV => Load.build(load) + case load: LoadsMV => Load.build(load, conversionPrefixes.loadPQSPrefix()) case other => throw ConversionException( s"Encountered unexpected load type: $other. I hate surprises!" diff --git a/src/test/resources/pfGrids/exampleGrid.json b/src/test/resources/pfGrids/exampleGrid.json index 2f9a7608..8e5b824b 100644 --- a/src/test/resources/pfGrids/exampleGrid.json +++ b/src/test/resources/pfGrids/exampleGrid.json @@ -421,13 +421,13 @@ "uknom": 33.0, "vtarget": 1.0, "conElms": [ - { - "id": "Grid.ElmNet\\LS/TR Schalter(1).ElmCoup", - "pfCls": "ElmCoup" - }, { "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\2-Wicklungstransformator.ElmTr2", "pfCls": "ElmTr2" + }, + { + "id": "Grid.ElmNet\\LS/TR Schalter(1).ElmCoup", + "pfCls": "ElmCoup" } ] }, @@ -439,11 +439,11 @@ "vtarget": 1.0, "conElms": [ { - "id": "Grid.ElmNet\\LS/TR Schalter(1).ElmCoup", + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S1.ElmCoup", "pfCls": "ElmCoup" }, { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S1.ElmCoup", + "id": "Grid.ElmNet\\LS/TR Schalter(1).ElmCoup", "pfCls": "ElmCoup" } ] @@ -989,77 +989,99 @@ { "id": "Grid.ElmNet\\Load_0011.ElmLod", "coslini": 0.8892877697944641, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 3.9357337951660156e+24, "busId": "Grid.ElmNet\\Bus_0011.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0012.ElmLod", "coslini": 0.9672796130180359, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 6.30634593963623e+24, "busId": "Grid.ElmNet\\Bus_0012.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0013.ElmLod", "coslini": 0.9187926650047302, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 1.4693195343017578e+25, "busId": "Grid.ElmNet\\Bus_0013.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0014.ElmLod", "coslini": 0.9480450749397278, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 1.5716551780700683e+25, "busId": "Grid.ElmNet\\Bus_0014.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0002.ElmLod", "coslini": 0.8630567789077759, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 2.514319038391113e+25, "busId": "Grid.ElmNet\\Bus_0002.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0003.ElmLod", "coslini": 0.9802591800689697, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 9.609703063964843e+25, "busId": "Grid.ElmNet\\Bus_0003.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0004.ElmLod", "coslini": 0.9966880679130554, + "i_scale": 1, "pf_recap": 1, + "scale0": 1.0, "slini": 4.795883560180664e+25, "busId": "Grid.ElmNet\\Bus_0004.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0005.ElmLod", "coslini": 0.9785497784614563, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 7.766594886779785e+24, "busId": "Grid.ElmNet\\Bus_0005.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0006.ElmLod", "coslini": 0.8309071660041809, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 1.3479243278503417e+25, "busId": "Grid.ElmNet\\Bus_0006.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0015.ElmLod", "coslini": 0.9480450749397278, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 1.5716551780700683e+25, "busId": "Grid.ElmNet\\Bus_0015.ElmTerm" }, { "id": "Grid.ElmNet\\Load_0010.ElmLod", "coslini": 0.8405709862709045, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 1.070700740814209e+25, "busId": "Grid.ElmNet\\Bus_0010.ElmTerm" } @@ -1068,14 +1090,18 @@ { "id": "Grid.ElmNet\\Niederspannungslast.ElmLodlv", "coslini": 0.9700000286102295, + "i_scale": 0, "pf_recap": 0, + "scale0": 1.0, "slini": 1.0, "busId": "Grid.ElmNet\\Bus_0007.ElmTerm" }, { "id": "Grid.ElmNet\\Niederspannungslast(1).ElmLodlv", "coslini": 1.0, + "i_scale": 0, "pf_recap": 0, + "scale0": 1.0, "slini": 0.0, "busId": "Grid.ElmNet\\Bus_0001.ElmTerm" } @@ -1084,14 +1110,18 @@ { "id": "Grid.ElmNet\\Load_0009.ElmLodmv", "coslini": 0.8999999761581421, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 3.2777778625488283e+25, "busId": "Grid.ElmNet\\Bus_0009.ElmTerm" }, { "id": "Grid.ElmNet\\Mittelspannungslast.ElmLodmv", "coslini": 1.0, + "i_scale": 1, "pf_recap": 0, + "scale0": 1.0, "slini": 0.0, "busId": "Grid.ElmNet\\Bus_0001.ElmTerm" } @@ -1139,16 +1169,16 @@ "pvs": [], "switches": [ { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S1.ElmCoup", + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S2.ElmCoup", "on_off": 1, "bus1Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\ON_Station_Lower.ElmTerm", - "bus2Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\1.ElmTerm" + "bus2Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\2.ElmTerm" }, { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S2.ElmCoup", + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S1.ElmCoup", "on_off": 1, "bus1Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\ON_Station_Lower.ElmTerm", - "bus2Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\2.ElmTerm" + "bus2Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\1.ElmTerm" }, { "id": "Grid.ElmNet\\LS/TR Schalter.ElmCoup", diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/common/ConverterTestData.scala b/src/test/scala/edu/ie3/powerFactory2psdm/common/ConverterTestData.scala index f14f252a..ecc61af7 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/common/ConverterTestData.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/common/ConverterTestData.scala @@ -79,6 +79,7 @@ import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories. import java.io.File import java.util.{Locale, UUID} +import scala.util.{Failure, Success, Try} object ConverterTestData extends LazyLogging { @@ -128,29 +129,34 @@ object ConverterTestData extends LazyLogging { resultType: T ) - logger.info("Building the grid model") - val testGridFile = s"${new File(".").getCanonicalPath}/src/test/resources/pfGrids/exampleGrid.json" - val rawGrid: RawPfGridModel = PfGridParser - .parse(testGridFile) - .getOrElse( - throw GridParsingException( - s"Couldn't parse the grid file $testGridFile" + def parseRawGrid: RawPfGridModel = + PfGridParser + .parse(testGridFile) + .getOrElse( + throw GridParsingException( + s"Couldn't parse the grid file $testGridFile" + ) ) - ) - - val preProcessedGrid: PreprocessedPfGridModel = PreprocessedPfGridModel.build( - rawGrid, - config.modelConfigs.sRatedSource, - config.modelConfigs.cosPhiSource - ) - logger.info("Sucessfully built the grid model") - - val id2node: Map[String, Node] = - preProcessedGrid.nodes.map(node => (node.id, node)).toMap + def buildPreProcessedTestGrid: PreprocessedPfGridModel = + Try { + PreprocessedPfGridModel.build( + parseRawGrid, + config.modelConfigs.sRatedSource, + config.modelConfigs.cosPhiSource + ) + } match { + case Failure(exc) => + throw TestException( + s"Could not build the grid in $testGridFile and therefore was not able to initialize the ConverterTestData. " + + s"This is probably due to the generated grid schema of the SchemaGenerator and the test grid being out of sync.", + exc + ) + case Success(grid) => grid + } val bus1Id = "Grid.ElmNet\\Bus_0001.ElmTerm" val bus2Id = "Grid.ElmNet\\Bus_0002.ElmTerm" @@ -701,4 +707,8 @@ object ConverterTestData extends LazyLogging { ) } + def main(args: Array[String]) = { + println("hi") + } + } diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridConverterSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridConverterSpec.scala index bd2de890..e7804686 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridConverterSpec.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridConverterSpec.scala @@ -18,8 +18,8 @@ class GridConverterSpec extends Matchers with AnyWordSpecLike { "A grid converter" should { val config = ConverterTestData.config - val rawGrid = ConverterTestData.rawGrid - val preProcessedGrid = ConverterTestData.preProcessedGrid + val rawGrid = ConverterTestData.parseRawGrid + val preProcessedGrid = ConverterTestData.buildPreProcessedTestGrid val result = GridConverter.convert(rawGrid, config) "convert all grid elements" in { diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridGraphBuilderSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridGraphBuilderSpec.scala index 672301c1..8e52ab04 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridGraphBuilderSpec.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/converter/GridGraphBuilderSpec.scala @@ -7,39 +7,44 @@ package edu.ie3.powerFactory2psdm.converter import edu.ie3.powerFactory2psdm.common.ConverterTestData.{ + buildPreProcessedTestGrid, subnet1Ids, subnet2Ids, subnet3Ids, - subnet4Ids, - preProcessedGrid + subnet4Ids } import edu.ie3.powerFactory2psdm.exception.pf.ElementConfigurationException import org.jgrapht.alg.connectivity.BiconnectivityInspector +import org.scalatest.BeforeAndAfter import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike import scala.jdk.CollectionConverters._ -class GridGraphBuilderSpec extends Matchers with AnyWordSpecLike { +class GridGraphBuilderSpec + extends Matchers + with AnyWordSpecLike + with BeforeAndAfter { "The GridGraphBuilder" should { + val preProcessedTestGrid = buildPreProcessedTestGrid val gridGraph = GridGraphBuilder.build( - preProcessedGrid.nodes, - preProcessedGrid.lines ++ preProcessedGrid.switches + preProcessedTestGrid.nodes, + preProcessedTestGrid.lines ++ preProcessedTestGrid.switches ) val inspect = new BiconnectivityInspector(gridGraph) val vertexSets = inspect.getConnectedComponents.asScala .map(graph => graph.vertexSet()) "add the correct number of nodes to the gridGraph" in { - gridGraph.vertexSet().size shouldBe preProcessedGrid.nodes.size + gridGraph.vertexSet().size shouldBe preProcessedTestGrid.nodes.size } "add the correct number of edges to the gridGraph" in { gridGraph .edgeSet() - .size shouldBe (preProcessedGrid.lines ++ preProcessedGrid.switches).size + .size shouldBe (preProcessedTestGrid.lines ++ preProcessedTestGrid.switches).size } "generate the correct number of subnets" in { diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/converter/SubnetBuilderSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/converter/SubnetBuilderSpec.scala index 7ae3a5c2..1652ac3f 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/converter/SubnetBuilderSpec.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/converter/SubnetBuilderSpec.scala @@ -7,16 +7,15 @@ package edu.ie3.powerFactory2psdm.converter import edu.ie3.powerFactory2psdm.common.ConverterTestData.{ - id2node, + buildPreProcessedTestGrid, subnet1Ids, - subnet2Ids, - preProcessedGrid + subnet2Ids } import edu.ie3.powerFactory2psdm.exception.pf.{ ElementConfigurationException, TestException } -import edu.ie3.powerFactory2psdm.model.entity.Subnet +import edu.ie3.powerFactory2psdm.model.entity.{Node, Subnet} import org.jgrapht.alg.connectivity.BiconnectivityInspector import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike @@ -24,14 +23,18 @@ import org.scalatest.wordspec.AnyWordSpecLike class SubnetBuilderSpec extends Matchers with AnyWordSpecLike { "The SubnetBuilder" should { + val preProcessedGrid = buildPreProcessedTestGrid val gridGraph = GridGraphBuilder.build( preProcessedGrid.nodes, - preProcessedGrid.lines ++ preProcessedGrid.switches + preProcessedGrid.lines ++ buildPreProcessedTestGrid.switches ) val subgraphs = new BiconnectivityInspector(gridGraph).getConnectedComponents + val id2node: Map[String, Node] = + buildPreProcessedTestGrid.nodes.map(node => (node.id, node)).toMap + "build a subnet for each subgraph" in { SubnetBuilder .buildSubnets(gridGraph, id2node) diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2WSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2WSpec.scala index 4d14de6b..8ddf6df6 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2WSpec.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2WSpec.scala @@ -47,7 +47,7 @@ class Transformer2WSpec extends Matchers with AnyWordSpecLike { "throw an exception if the type id is missing" in { val trafo = input.copy(typeId = None) val exc = intercept[MissingParameterException](Transformer2W.build(trafo)) - exc.getMessage shouldBe s"Trafo2w: $id has no type id." + exc.getMessage shouldBe s"Trafo2w: $id has no type id. Transformer conversion without specified types is not supported." } "throw an exception if the tap pos is missing" in { From 0a306b8c9ddb34ab58d2d0cb16309b266a6221f0 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Thu, 28 Oct 2021 13:17:40 +0200 Subject: [PATCH 14/24] fix test --- .../ie3/powerFactory2psdm/model/entity/Transformer2WSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2WSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2WSpec.scala index 8ddf6df6..65c19a1b 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2WSpec.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/model/entity/Transformer2WSpec.scala @@ -47,7 +47,7 @@ class Transformer2WSpec extends Matchers with AnyWordSpecLike { "throw an exception if the type id is missing" in { val trafo = input.copy(typeId = None) val exc = intercept[MissingParameterException](Transformer2W.build(trafo)) - exc.getMessage shouldBe s"Trafo2w: $id has no type id. Transformer conversion without specified types is not supported." + exc.getMessage shouldBe s"Trafo2w: $id has no type. Transformer conversion without specified types is not supported." } "throw an exception if the tap pos is missing" in { From 5938206dccd766e539c3eb656980f43b2f2d2b3d Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Thu, 18 Nov 2021 10:48:33 +0100 Subject: [PATCH 15/24] remove unused import --- src/main/python/powerFactory2json/pf2json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/python/powerFactory2json/pf2json.py b/src/main/python/powerFactory2json/pf2json.py index 487a3c33..6f7473a3 100644 --- a/src/main/python/powerFactory2json/pf2json.py +++ b/src/main/python/powerFactory2json/pf2json.py @@ -7,7 +7,7 @@ # fixme: Delete reload after development import importlib importlib.reload(pf2jsonUtils) -from pf2jsonUtils import attributes4export, elements4export, nested_elements4export, reserved_keywords +from pf2jsonUtils import attributes4export, elements4export, reserved_keywords ################# # Configuration # From c8521a576a8323ec74c3a9a29f4e5091d8840eeb Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Thu, 18 Nov 2021 11:04:19 +0100 Subject: [PATCH 16/24] recreate schema --- .../model/RawPfGridModel.scala | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala index 8ef1ed7c..c1d79689 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala @@ -1,9 +1,3 @@ -/* - * © 2021. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - package edu.ie3.powerFactory2psdm.model import edu.ie3.powerFactory2psdm.model.RawPfGridModel.{ ExtGrid, @@ -61,8 +55,8 @@ object RawPfGridModel { busId: Option[String], id: Option[String], coslini: Option[Double], - scale0: Option[Double], slini: Option[Double], + scale0: Option[Double], iScale: Option[Double] ) @@ -77,12 +71,12 @@ object RawPfGridModel { ) final case class StatGen( - sgn: Option[Double], cCategory: Option[String], - pfRecap: Option[Double], busId: Option[String], id: Option[String], sgini: Option[Double], + sgn: Option[Double], + pfRecap: Option[Double], cosn: Option[Double], cosgini: Option[Double] ) @@ -103,20 +97,20 @@ object RawPfGridModel { final case class ExtGrid(id: Option[String], busId: Option[String]) final case class TrafoTypes2w( + utrnH: Option[Double], nntap0: Option[Double], + curmg: Option[Double], pfe: Option[Double], - uktr: Option[Double], id: Option[String], ntpmn: Option[Double], dutap: Option[Double], - strn: Option[Double], + phitr: Option[Double], utrnL: Option[Double], - curmg: Option[Double], + strn: Option[Double], tapSide: Option[Double], + uktr: Option[Double], ntpmx: Option[Double], - pcutr: Option[Double], - phitr: Option[Double], - utrnH: Option[Double] + pcutr: Option[Double] ) final case class ProjectSettings( @@ -130,8 +124,8 @@ object RawPfGridModel { busId: Option[String], id: Option[String], coslini: Option[Double], - scale0: Option[Double], slini: Option[Double], + scale0: Option[Double], iScale: Option[Double] ) @@ -161,8 +155,8 @@ object RawPfGridModel { busId: Option[String], id: Option[String], coslini: Option[Double], - scale0: Option[Double], slini: Option[Double], + scale0: Option[Double], iScale: Option[Double] ) From 263f16445422fc6407da1f12bc9713f14002e7a8 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Thu, 18 Nov 2021 11:05:52 +0100 Subject: [PATCH 17/24] fmt --- .../edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala index c1d79689..43bcfe67 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/RawPfGridModel.scala @@ -1,3 +1,9 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + package edu.ie3.powerFactory2psdm.model import edu.ie3.powerFactory2psdm.model.RawPfGridModel.{ ExtGrid, From 2a715d6c53db009247a2f9f957840d84b47cff68 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Thu, 18 Nov 2021 12:05:46 +0100 Subject: [PATCH 18/24] udpate test grid --- src/test/resources/pfGrids/exampleGrid.json | 118 ++++++++++---------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/test/resources/pfGrids/exampleGrid.json b/src/test/resources/pfGrids/exampleGrid.json index 8e5b824b..1a534fa4 100644 --- a/src/test/resources/pfGrids/exampleGrid.json +++ b/src/test/resources/pfGrids/exampleGrid.json @@ -439,11 +439,11 @@ "vtarget": 1.0, "conElms": [ { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S1.ElmCoup", + "id": "Grid.ElmNet\\LS/TR Schalter(1).ElmCoup", "pfCls": "ElmCoup" }, { - "id": "Grid.ElmNet\\LS/TR Schalter(1).ElmCoup", + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S1.ElmCoup", "pfCls": "ElmCoup" } ] @@ -897,10 +897,10 @@ "pfe": 0.0, "phitr": 0.0, "strn": 100.0, - "tap_side": 0, + "tapSide": 0, "uktr": 20.91200065612793, - "utrn_h": 132.0, - "utrn_l": 1.0 + "utrnH": 132.0, + "utrnL": 1.0 }, { "id": "TypTr2 0004 to 0009.TypTr2", @@ -913,10 +913,10 @@ "pfe": 0.0, "phitr": 0.0, "strn": 100.0, - "tap_side": 0, + "tapSide": 0, "uktr": 55.61800003051758, - "utrn_h": 132.0, - "utrn_l": 33.0 + "utrnH": 132.0, + "utrnL": 33.0 }, { "id": "TypTr2 0007 to 0008.TypTr2", @@ -929,10 +929,10 @@ "pfe": 0.0, "phitr": 0.0, "strn": 100.0, - "tap_side": 0, + "tapSide": 0, "uktr": 17.614999771118164, - "utrn_h": 11.0, - "utrn_l": 1.0 + "utrnH": 11.0, + "utrnL": 1.0 }, { "id": "TypTr2 0007 to 0009.TypTr2", @@ -945,10 +945,10 @@ "pfe": 0.0, "phitr": 0.0, "strn": 100.0, - "tap_side": 0, + "tapSide": 0, "uktr": 11.000999450683594, - "utrn_h": 33.0, - "utrn_l": 1.0 + "utrnH": 33.0, + "utrnL": 1.0 }, { "id": "\\Lib.IntLibrary\\Types\\Transf\\Tr2\\50Hz\\Dis\\10kV\\0.01 MVA 10/0.4 kV DT 10 SGB.TypTr2", @@ -961,10 +961,10 @@ "pfe": 0.11999999731779099, "phitr": 0.0, "strn": 0.009999999776482582, - "tap_side": 0, + "tapSide": 0, "uktr": 4.0, - "utrn_h": 10.0, - "utrn_l": 0.4000000059604645 + "utrnH": 10.0, + "utrnL": 0.4000000059604645 }, { "id": "TypTr2 0005 to 0006.TypTr2", @@ -977,10 +977,10 @@ "pfe": 0.0, "phitr": 0.0, "strn": 100.0, - "tap_side": 0, + "tapSide": 0, "uktr": 25.20199966430664, - "utrn_h": 132.0, - "utrn_l": 33.0 + "utrnH": 132.0, + "utrnL": 33.0 } ], "trafos3w": [], @@ -989,8 +989,8 @@ { "id": "Grid.ElmNet\\Load_0011.ElmLod", "coslini": 0.8892877697944641, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 3.9357337951660156e+24, "busId": "Grid.ElmNet\\Bus_0011.ElmTerm" @@ -998,8 +998,8 @@ { "id": "Grid.ElmNet\\Load_0012.ElmLod", "coslini": 0.9672796130180359, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 6.30634593963623e+24, "busId": "Grid.ElmNet\\Bus_0012.ElmTerm" @@ -1007,8 +1007,8 @@ { "id": "Grid.ElmNet\\Load_0013.ElmLod", "coslini": 0.9187926650047302, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 1.4693195343017578e+25, "busId": "Grid.ElmNet\\Bus_0013.ElmTerm" @@ -1016,8 +1016,8 @@ { "id": "Grid.ElmNet\\Load_0014.ElmLod", "coslini": 0.9480450749397278, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 1.5716551780700683e+25, "busId": "Grid.ElmNet\\Bus_0014.ElmTerm" @@ -1025,8 +1025,8 @@ { "id": "Grid.ElmNet\\Load_0002.ElmLod", "coslini": 0.8630567789077759, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 2.514319038391113e+25, "busId": "Grid.ElmNet\\Bus_0002.ElmTerm" @@ -1034,8 +1034,8 @@ { "id": "Grid.ElmNet\\Load_0003.ElmLod", "coslini": 0.9802591800689697, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 9.609703063964843e+25, "busId": "Grid.ElmNet\\Bus_0003.ElmTerm" @@ -1043,8 +1043,8 @@ { "id": "Grid.ElmNet\\Load_0004.ElmLod", "coslini": 0.9966880679130554, - "i_scale": 1, - "pf_recap": 1, + "iScale": 1, + "pfRecap": 1, "scale0": 1.0, "slini": 4.795883560180664e+25, "busId": "Grid.ElmNet\\Bus_0004.ElmTerm" @@ -1052,8 +1052,8 @@ { "id": "Grid.ElmNet\\Load_0005.ElmLod", "coslini": 0.9785497784614563, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 7.766594886779785e+24, "busId": "Grid.ElmNet\\Bus_0005.ElmTerm" @@ -1061,8 +1061,8 @@ { "id": "Grid.ElmNet\\Load_0006.ElmLod", "coslini": 0.8309071660041809, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 1.3479243278503417e+25, "busId": "Grid.ElmNet\\Bus_0006.ElmTerm" @@ -1070,8 +1070,8 @@ { "id": "Grid.ElmNet\\Load_0015.ElmLod", "coslini": 0.9480450749397278, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 1.5716551780700683e+25, "busId": "Grid.ElmNet\\Bus_0015.ElmTerm" @@ -1079,8 +1079,8 @@ { "id": "Grid.ElmNet\\Load_0010.ElmLod", "coslini": 0.8405709862709045, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 1.070700740814209e+25, "busId": "Grid.ElmNet\\Bus_0010.ElmTerm" @@ -1090,8 +1090,8 @@ { "id": "Grid.ElmNet\\Niederspannungslast.ElmLodlv", "coslini": 0.9700000286102295, - "i_scale": 0, - "pf_recap": 0, + "iScale": 0, + "pfRecap": 0, "scale0": 1.0, "slini": 1.0, "busId": "Grid.ElmNet\\Bus_0007.ElmTerm" @@ -1099,8 +1099,8 @@ { "id": "Grid.ElmNet\\Niederspannungslast(1).ElmLodlv", "coslini": 1.0, - "i_scale": 0, - "pf_recap": 0, + "iScale": 0, + "pfRecap": 0, "scale0": 1.0, "slini": 0.0, "busId": "Grid.ElmNet\\Bus_0001.ElmTerm" @@ -1110,8 +1110,8 @@ { "id": "Grid.ElmNet\\Load_0009.ElmLodmv", "coslini": 0.8999999761581421, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 3.2777778625488283e+25, "busId": "Grid.ElmNet\\Bus_0009.ElmTerm" @@ -1119,8 +1119,8 @@ { "id": "Grid.ElmNet\\Mittelspannungslast.ElmLodmv", "coslini": 1.0, - "i_scale": 1, - "pf_recap": 0, + "iScale": 1, + "pfRecap": 0, "scale0": 1.0, "slini": 0.0, "busId": "Grid.ElmNet\\Bus_0001.ElmTerm" @@ -1132,7 +1132,7 @@ "cCategory": "Fotovoltaik", "cosgini": 1.0, "cosn": 0.800000011920929, - "pf_recap": 0, + "pfRecap": 0, "sgini": 0.0, "sgn": 1.0, "busId": "Grid.ElmNet\\Bus_0006.ElmTerm" @@ -1169,26 +1169,26 @@ "pvs": [], "switches": [ { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S2.ElmCoup", - "on_off": 1, + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S1.ElmCoup", + "onOff": 1, "bus1Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\ON_Station_Lower.ElmTerm", - "bus2Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\2.ElmTerm" + "bus2Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\1.ElmTerm" }, { - "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S1.ElmCoup", - "on_off": 1, + "id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\S2.ElmCoup", + "onOff": 1, "bus1Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\ON_Station_Lower.ElmTerm", - "bus2Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\1.ElmTerm" + "bus2Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\2.ElmTerm" }, { "id": "Grid.ElmNet\\LS/TR Schalter.ElmCoup", - "on_off": 1, + "onOff": 1, "bus1Id": "Grid.ElmNet\\Bus_0014.ElmTerm", "bus2Id": "Grid.ElmNet\\Bus_0015.ElmTerm" }, { "id": "Grid.ElmNet\\LS/TR Schalter(1).ElmCoup", - "on_off": 1, + "onOff": 1, "bus1Id": "Grid.ElmNet\\Ortsnetzstation.ElmTrfstat\\1.ElmTerm", "bus2Id": "Grid.ElmNet\\Bus_0015.ElmTerm" } From fa6c3e84e0c9f2c8f9fb20aabefabdb54a85e948 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Thu, 18 Nov 2021 16:44:59 +0100 Subject: [PATCH 19/24] be more type specific --- .../converter/StaticGeneratorConverter.scala | 57 +++++++------------ .../generator/WecInputGenerator.scala | 7 +-- 2 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala index 45d7f44b..8d56d73b 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala @@ -8,35 +8,21 @@ package edu.ie3.powerFactory2psdm.converter import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.input.NodeInput -import edu.ie3.datamodel.models.input.system.{ - FixedFeedInInput, - PvInput, - WecInput -} +import edu.ie3.datamodel.models.input.system.{FixedFeedInInput, PvInput, SystemParticipantInput, WecInput} import edu.ie3.powerFactory2psdm.config.ConversionConfig.StatGenModelConfigs -import edu.ie3.powerFactory2psdm.config.model.PvConversionConfig.{ - PvFixedFeedIn, - PvModelGeneration -} -import edu.ie3.powerFactory2psdm.config.model.WecConversionConfig.{ - WecFixedFeedIn, - WecModelGeneration -} +import edu.ie3.powerFactory2psdm.config.model.PvConversionConfig.{PvFixedFeedIn, PvModelGeneration} +import edu.ie3.powerFactory2psdm.config.model.WecConversionConfig.{WecFixedFeedIn, WecModelGeneration} import edu.ie3.powerFactory2psdm.exception.pf.ConversionException import edu.ie3.powerFactory2psdm.generator.{PvInputGenerator, WecInputGenerator} import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator -import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.{ - OTHER, - PV, - WEC -} +import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.{OTHER, PV, WEC} -import scala.util.{Failure, Success} +import scala.util.{Failure, Success, Try} object StaticGeneratorConverter extends LazyLogging { /** * Container class to house the different PSDM models resulting from the - * conversion of the [[StaticGenerator]] s + * conversion of the [[StaticGenerator]]s * * @param fixedFeedIns * fixed feed ins @@ -62,14 +48,15 @@ object StaticGeneratorConverter extends LazyLogging { val convertedModels = input.foldLeft(emptyModelContainer) { case ((fixed, pv, wec), statGen) => convert(statGen, conversionConfig, nodes) match { - case x: FixedFeedInInput => (x :: fixed, pv, wec) - case x: PvInput => (fixed, x :: pv, wec) - case x: WecInput => (fixed, pv, x :: wec) - case () => (fixed, pv, wec) - case x => { + case x: Success[FixedFeedInInput] => (x.value :: fixed, pv, wec) + case x: Success[PvInput] => (fixed, x .value:: pv, wec) + case x: Success[WecInput] => (fixed, pv, x.value :: wec) + case Failure(exc) => + logger error exc.getMessage + (fixed, pv, wec) + case x => logger error s"Got an unexpected model: $x. This will be ignored and not converted!" (fixed, pv, wec) - } } } StatGenModelContainer( @@ -83,7 +70,7 @@ object StaticGeneratorConverter extends LazyLogging { statGen: StaticGenerator, conversionConfig: StatGenModelConfigs, nodes: Map[String, NodeInput] - ): Any = { + ): Try[SystemParticipantInput] = { val node = NodeConverter.getNode(statGen.busId, nodes) match { case Failure(exc) => throw ConversionException( @@ -101,13 +88,13 @@ object StaticGeneratorConverter extends LazyLogging { .getOrElse(conversionConfig.pvConfig.conversionMode) conversionMode match { case fixedFeedIn: PvFixedFeedIn => - FixedFeedInConverter.convert( + Success(FixedFeedInConverter.convert( statGen, node, fixedFeedIn.qCharacteristic - ) + )) case modelGeneration: PvModelGeneration => - PvInputGenerator.generate(statGen, node, modelGeneration) + Success(PvInputGenerator.generate(statGen, node, modelGeneration)) } case WEC => val maybeIndividualConfig = @@ -117,17 +104,17 @@ object StaticGeneratorConverter extends LazyLogging { .getOrElse(conversionConfig.wecConfig.conversionMode) conversionMode match { case fixedFeedIn: WecFixedFeedIn => - FixedFeedInConverter.convert( + Success(FixedFeedInConverter.convert( statGen, node, fixedFeedIn.qCharacteristic - ) + )) case modelGeneration: WecModelGeneration => - WecInputGenerator.generate(statGen, node, modelGeneration) + Success(WecInputGenerator.generate(statGen, node, modelGeneration)) } case OTHER => - logger error s"Generator: ${statGen.id} will not be converted as its category is marked as $OTHER. " + - s"For supported categories check class [[StatGenCategories]]" + Failure(ConversionException(s"Generator: ${statGen.id} will not be converted as its category is marked as $OTHER. " + + s"For supported categories check class [[StatGenCategories]]")) } } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/generator/WecInputGenerator.scala b/src/main/scala/edu/ie3/powerFactory2psdm/generator/WecInputGenerator.scala index d5ab251b..6f0df81f 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/generator/WecInputGenerator.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/generator/WecInputGenerator.scala @@ -31,19 +31,19 @@ object WecInputGenerator { * @param params * parameters for generating missing parameters * @return - * [[WecInput]] and a [[WecTypeInput]] that replace the [[StaticGenerator]] + * [[WecInput]] that replaces the [[StaticGenerator]] */ def generate( input: StaticGenerator, node: NodeInput, params: WecModelGeneration - ): (WecInput, WecTypeInput) = { + ): WecInput = { val cosPhiRated = ConversionHelper.determineCosPhiRated(input) val qCharacteristics: ReactivePowerCharacteristic = ConversionHelper .convertQCharacteristic(params.qCharacteristic, cosPhiRated) val wecTypeInput = WecTypeGenerator.convert(input, params) - val wecInput = new WecInput( + new WecInput( UUID.randomUUID(), input.id, node, @@ -51,7 +51,6 @@ object WecInputGenerator { wecTypeInput, false ) - (wecInput, wecTypeInput) } } From 727e03c9752aff45b5628f0e5a7c5f7b0b182b91 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Thu, 18 Nov 2021 16:49:36 +0100 Subject: [PATCH 20/24] docstring --- .../config/model/DefaultModelConfig.scala | 12 +++ .../converter/StaticGeneratorConverter.scala | 73 ++++++++++++------- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala index 682818e0..8c61b627 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala @@ -26,4 +26,16 @@ trait DefaultModelConfig[M <: ModelConversionMode, I <: IndividualModelConfig[ .getOrElse(Nil) .map(conf => conf.conversionMode) } + + /** Return individual conversion mode of the model if there is one or + * otherwise the default one + * + * @param modelId the model id for which to retrieve the conversion mode + * @return + */ + def getConversionMode(modelId: String): M = { + getIndividualModelConfig(modelId) + .map(config => config.conversionMode) + .getOrElse(conversionMode) + } } diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala index 8d56d73b..06fc7fcc 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala @@ -8,14 +8,29 @@ package edu.ie3.powerFactory2psdm.converter import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.input.NodeInput -import edu.ie3.datamodel.models.input.system.{FixedFeedInInput, PvInput, SystemParticipantInput, WecInput} +import edu.ie3.datamodel.models.input.system.{ + FixedFeedInInput, + PvInput, + SystemParticipantInput, + WecInput +} import edu.ie3.powerFactory2psdm.config.ConversionConfig.StatGenModelConfigs -import edu.ie3.powerFactory2psdm.config.model.PvConversionConfig.{PvFixedFeedIn, PvModelGeneration} -import edu.ie3.powerFactory2psdm.config.model.WecConversionConfig.{WecFixedFeedIn, WecModelGeneration} +import edu.ie3.powerFactory2psdm.config.model.PvConversionConfig.{ + PvFixedFeedIn, + PvModelGeneration +} +import edu.ie3.powerFactory2psdm.config.model.WecConversionConfig.{ + WecFixedFeedIn, + WecModelGeneration +} import edu.ie3.powerFactory2psdm.exception.pf.ConversionException import edu.ie3.powerFactory2psdm.generator.{PvInputGenerator, WecInputGenerator} import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator -import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.{OTHER, PV, WEC} +import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.{ + OTHER, + PV, + WEC +} import scala.util.{Failure, Success, Try} @@ -49,9 +64,9 @@ object StaticGeneratorConverter extends LazyLogging { case ((fixed, pv, wec), statGen) => convert(statGen, conversionConfig, nodes) match { case x: Success[FixedFeedInInput] => (x.value :: fixed, pv, wec) - case x: Success[PvInput] => (fixed, x .value:: pv, wec) + case x: Success[PvInput] => (fixed, x.value :: pv, wec) case x: Success[WecInput] => (fixed, pv, x.value :: wec) - case Failure(exc) => + case Failure(exc) => logger error exc.getMessage (fixed, pv, wec) case x => @@ -81,40 +96,42 @@ object StaticGeneratorConverter extends LazyLogging { } statGen.category match { case PV => - val maybeIndividualConfig = - conversionConfig.pvConfig.getIndividualModelConfig(statGen.id) - val conversionMode = maybeIndividualConfig - .map(config => config.conversionMode) - .getOrElse(conversionConfig.pvConfig.conversionMode) + val conversionMode = + conversionConfig.pvConfig.getConversionMode(statGen.id) conversionMode match { case fixedFeedIn: PvFixedFeedIn => - Success(FixedFeedInConverter.convert( - statGen, - node, - fixedFeedIn.qCharacteristic - )) + Success( + FixedFeedInConverter.convert( + statGen, + node, + fixedFeedIn.qCharacteristic + ) + ) case modelGeneration: PvModelGeneration => Success(PvInputGenerator.generate(statGen, node, modelGeneration)) } case WEC => - val maybeIndividualConfig = - conversionConfig.wecConfig.getIndividualModelConfig(statGen.id) - val conversionMode = maybeIndividualConfig - .map(config => config.conversionMode) - .getOrElse(conversionConfig.wecConfig.conversionMode) + val conversionMode = + conversionConfig.wecConfig.getConversionMode(statGen.id) conversionMode match { case fixedFeedIn: WecFixedFeedIn => - Success(FixedFeedInConverter.convert( - statGen, - node, - fixedFeedIn.qCharacteristic - )) + Success( + FixedFeedInConverter.convert( + statGen, + node, + fixedFeedIn.qCharacteristic + ) + ) case modelGeneration: WecModelGeneration => Success(WecInputGenerator.generate(statGen, node, modelGeneration)) } case OTHER => - Failure(ConversionException(s"Generator: ${statGen.id} will not be converted as its category is marked as $OTHER. " + - s"For supported categories check class [[StatGenCategories]]")) + Failure( + ConversionException( + s"Generator: ${statGen.id} will not be converted as its category is marked as $OTHER. " + + s"For supported categories check class [[StatGenCategories]]" + ) + ) } } From f63f92061180154fc1a08c788c46c3f2b51f72cf Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Mon, 22 Nov 2021 08:43:25 +0100 Subject: [PATCH 21/24] add tests --- .../config/model/DefaultModelConfig.scala | 3 +- .../converter/StaticGeneratorConverter.scala | 8 ++-- .../model/PreprocessedPfGridModel.scala | 2 +- .../StaticGeneratorConverterSpec.scala | 40 +++++++++++++++++++ .../generator/WecInputGeneratorSpec.scala | 4 +- 5 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 src/test/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverterSpec.scala diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala index 8c61b627..7c50aa4d 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/config/model/DefaultModelConfig.scala @@ -30,7 +30,8 @@ trait DefaultModelConfig[M <: ModelConversionMode, I <: IndividualModelConfig[ /** Return individual conversion mode of the model if there is one or * otherwise the default one * - * @param modelId the model id for which to retrieve the conversion mode + * @param modelId + * the model id for which to retrieve the conversion mode * @return */ def getConversionMode(modelId: String): M = { diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala index 06fc7fcc..33ae2719 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala @@ -63,9 +63,11 @@ object StaticGeneratorConverter extends LazyLogging { val convertedModels = input.foldLeft(emptyModelContainer) { case ((fixed, pv, wec), statGen) => convert(statGen, conversionConfig, nodes) match { - case x: Success[FixedFeedInInput] => (x.value :: fixed, pv, wec) - case x: Success[PvInput] => (fixed, x.value :: pv, wec) - case x: Success[WecInput] => (fixed, pv, x.value :: wec) + case Success(model) => model match { + case x: FixedFeedInInput => (x :: fixed, pv, wec) + case x: PvInput => (fixed, x :: pv, wec) + case x: WecInput => (fixed, pv, x :: wec) + } case Failure(exc) => logger error exc.getMessage (fixed, pv, wec) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala b/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala index 05bdd999..dd6a15e4 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/model/PreprocessedPfGridModel.scala @@ -206,7 +206,7 @@ object PreprocessedPfGridModel extends LazyLogging { case load: LoadsMV => Load.build(load, conversionPrefixes.loadPQSPrefix()) case other => throw ConversionException( - s"Encountered unexpected load type: $other. I hate surprises!" + s"Encountered unexpected load type: $other. Processing of this load type is not supported." ) } val staticGenerators = rawStaticGenerators.map(statGen => diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverterSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverterSpec.scala new file mode 100644 index 00000000..ee661a98 --- /dev/null +++ b/src/test/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverterSpec.scala @@ -0,0 +1,40 @@ +package edu.ie3.powerFactory2psdm.converter + +import edu.ie3.powerFactory2psdm.common.ConverterTestData +import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.FixedQCharacteristic +import edu.ie3.powerFactory2psdm.config.model.PvConversionConfig.{IndividualPvConfig, PvFixedFeedIn} +import edu.ie3.powerFactory2psdm.config.model.WecConversionConfig.{IndividualWecConfig, WecFixedFeedIn} +import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.{PV, WEC} +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpecLike + +class StaticGeneratorConverterSpec extends Matchers with AnyWordSpecLike { + "A static generator converter" should { + "convert a list of static generators correctly" in { + val conversionPair = ConverterTestData.getStaticGenerator2FixedFeedInPair("someStatGen") + val statGen = conversionPair.input + val statGenModelConfigs = ConverterTestData.config.modelConfigs + + val inputWecModel = statGen.copy(id = "WecModel", category = WEC) + val inputWecFixedFeedIn = statGen.copy(id = "WecFixedFeedIn", category = WEC) + val individualWecConfig = IndividualWecConfig(Set("WecFixedFeedIn"), WecFixedFeedIn(FixedQCharacteristic)) + val wecConversionConfig = statGenModelConfigs.wecConfig.copy(individualConfigs = Some(List(individualWecConfig))) + + val inputPvModel = statGen.copy(id = "PvModel", category = PV) + val inputPvFixedFeedIn = statGen.copy(id = "PvFixedFeedIn", category = PV) + val individualPvConfig = IndividualPvConfig(Set("PvFixedFeedIn"), PvFixedFeedIn(FixedQCharacteristic)) + val pvConversionConfig = statGenModelConfigs.pvConfig.copy(individualConfigs = Some(List(individualPvConfig))) + + val inputs = List(statGen, inputWecModel, inputWecFixedFeedIn, inputPvModel, inputPvFixedFeedIn) + val node = ConverterTestData.getNodePair("someNode").result + val nodesMap = Map("someNode" -> node) + + val actual = StaticGeneratorConverter.convert(inputs, statGenModelConfigs.copy(pvConfig = pvConversionConfig, wecConfig = wecConversionConfig), nodesMap) + + actual.fixedFeedIns.size shouldBe 2 + actual.wecInputs.size shouldBe 1 + actual.pvInputs.size shouldBe 1 + + } + } +} diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/generator/WecInputGeneratorSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/generator/WecInputGeneratorSpec.scala index 70fe3c2e..fb2c0b31 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/generator/WecInputGeneratorSpec.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/generator/WecInputGeneratorSpec.scala @@ -26,7 +26,7 @@ class WecInputGeneratorSpec extends Matchers with AnyWordSpecLike { "generate a WecInput correctly" in { val expected = generationPair.resultModel val actual = - WecInputGenerator.generate(input, node, modelGenerationConfig)._1 + WecInputGenerator.generate(input, node, modelGenerationConfig) actual.getId shouldBe expected.getId actual.getNode shouldBe expected.getNode @@ -35,7 +35,7 @@ class WecInputGeneratorSpec extends Matchers with AnyWordSpecLike { "generate a WecTypeInput correctly" in { val expected = generationPair.resultType val actual = - WecInputGenerator.generate(input, node, modelGenerationConfig)._2 + WecInputGenerator.generate(input, node, modelGenerationConfig).getType actual.getsRated shouldBe expected.getsRated actual.getEtaConv shouldBe expected.getEtaConv From 6d96bd1c00aa6de20e60bd13a8816d5d307083a7 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Mon, 22 Nov 2021 08:47:06 +0100 Subject: [PATCH 22/24] fmt --- .../converter/StaticGeneratorConverter.scala | 11 ++-- .../StaticGeneratorConverterSpec.scala | 62 +++++++++++++++---- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala index 33ae2719..743a7bb2 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverter.scala @@ -63,11 +63,12 @@ object StaticGeneratorConverter extends LazyLogging { val convertedModels = input.foldLeft(emptyModelContainer) { case ((fixed, pv, wec), statGen) => convert(statGen, conversionConfig, nodes) match { - case Success(model) => model match { - case x: FixedFeedInInput => (x :: fixed, pv, wec) - case x: PvInput => (fixed, x :: pv, wec) - case x: WecInput => (fixed, pv, x :: wec) - } + case Success(model) => + model match { + case x: FixedFeedInInput => (x :: fixed, pv, wec) + case x: PvInput => (fixed, x :: pv, wec) + case x: WecInput => (fixed, pv, x :: wec) + } case Failure(exc) => logger error exc.getMessage (fixed, pv, wec) diff --git a/src/test/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverterSpec.scala b/src/test/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverterSpec.scala index ee661a98..4247511c 100644 --- a/src/test/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverterSpec.scala +++ b/src/test/scala/edu/ie3/powerFactory2psdm/converter/StaticGeneratorConverterSpec.scala @@ -1,35 +1,71 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + package edu.ie3.powerFactory2psdm.converter import edu.ie3.powerFactory2psdm.common.ConverterTestData import edu.ie3.powerFactory2psdm.config.ConversionConfigUtils.FixedQCharacteristic -import edu.ie3.powerFactory2psdm.config.model.PvConversionConfig.{IndividualPvConfig, PvFixedFeedIn} -import edu.ie3.powerFactory2psdm.config.model.WecConversionConfig.{IndividualWecConfig, WecFixedFeedIn} -import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.{PV, WEC} +import edu.ie3.powerFactory2psdm.config.model.PvConversionConfig.{ + IndividualPvConfig, + PvFixedFeedIn +} +import edu.ie3.powerFactory2psdm.config.model.WecConversionConfig.{ + IndividualWecConfig, + WecFixedFeedIn +} +import edu.ie3.powerFactory2psdm.model.entity.StaticGenerator.StatGenCategories.{ + PV, + WEC +} import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike class StaticGeneratorConverterSpec extends Matchers with AnyWordSpecLike { "A static generator converter" should { "convert a list of static generators correctly" in { - val conversionPair = ConverterTestData.getStaticGenerator2FixedFeedInPair("someStatGen") + val conversionPair = + ConverterTestData.getStaticGenerator2FixedFeedInPair("someStatGen") val statGen = conversionPair.input val statGenModelConfigs = ConverterTestData.config.modelConfigs val inputWecModel = statGen.copy(id = "WecModel", category = WEC) - val inputWecFixedFeedIn = statGen.copy(id = "WecFixedFeedIn", category = WEC) - val individualWecConfig = IndividualWecConfig(Set("WecFixedFeedIn"), WecFixedFeedIn(FixedQCharacteristic)) - val wecConversionConfig = statGenModelConfigs.wecConfig.copy(individualConfigs = Some(List(individualWecConfig))) + val inputWecFixedFeedIn = + statGen.copy(id = "WecFixedFeedIn", category = WEC) + val individualWecConfig = IndividualWecConfig( + Set("WecFixedFeedIn"), + WecFixedFeedIn(FixedQCharacteristic) + ) + val wecConversionConfig = statGenModelConfigs.wecConfig + .copy(individualConfigs = Some(List(individualWecConfig))) val inputPvModel = statGen.copy(id = "PvModel", category = PV) val inputPvFixedFeedIn = statGen.copy(id = "PvFixedFeedIn", category = PV) - val individualPvConfig = IndividualPvConfig(Set("PvFixedFeedIn"), PvFixedFeedIn(FixedQCharacteristic)) - val pvConversionConfig = statGenModelConfigs.pvConfig.copy(individualConfigs = Some(List(individualPvConfig))) + val individualPvConfig = IndividualPvConfig( + Set("PvFixedFeedIn"), + PvFixedFeedIn(FixedQCharacteristic) + ) + val pvConversionConfig = statGenModelConfigs.pvConfig + .copy(individualConfigs = Some(List(individualPvConfig))) - val inputs = List(statGen, inputWecModel, inputWecFixedFeedIn, inputPvModel, inputPvFixedFeedIn) - val node = ConverterTestData.getNodePair("someNode").result - val nodesMap = Map("someNode" -> node) + val inputs = List( + statGen, + inputWecModel, + inputWecFixedFeedIn, + inputPvModel, + inputPvFixedFeedIn + ) + val node = ConverterTestData.getNodePair("someNode").result + val nodesMap = Map("someNode" -> node) - val actual = StaticGeneratorConverter.convert(inputs, statGenModelConfigs.copy(pvConfig = pvConversionConfig, wecConfig = wecConversionConfig), nodesMap) + val actual = StaticGeneratorConverter.convert( + inputs, + statGenModelConfigs + .copy(pvConfig = pvConversionConfig, wecConfig = wecConversionConfig), + nodesMap + ) actual.fixedFeedIns.size shouldBe 2 actual.wecInputs.size shouldBe 1 From 069de840f09137fd25b68890343688fe2acc2d2e Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Wed, 24 Nov 2021 08:09:25 +0100 Subject: [PATCH 23/24] update test grid --- src/test/resources/pfGrids/exampleGrid.json | 112 ++++++++++---------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/src/test/resources/pfGrids/exampleGrid.json b/src/test/resources/pfGrids/exampleGrid.json index 1a534fa4..bf59880c 100644 --- a/src/test/resources/pfGrids/exampleGrid.json +++ b/src/test/resources/pfGrids/exampleGrid.json @@ -477,14 +477,14 @@ ], "lines": [ { - "id": "Grid.ElmNet\\Line_0002_0003.ElmLne", + "id": "Grid.ElmNet\\Line_0002_0005.ElmLne", "GPScoords": [ [] ], "dline": 1.0, "bus1Id": "Grid.ElmNet\\Bus_0002.ElmTerm", - "bus2Id": "Grid.ElmNet\\Bus_0003.ElmTerm", - "typeId": "TypLne 0002 to 0003.TypLne" + "bus2Id": "Grid.ElmNet\\Bus_0005.ElmTerm", + "typeId": "TypLne 0002 to 0005.TypLne" }, { "id": "Grid.ElmNet\\Line_0010_0011.ElmLne", @@ -496,16 +496,6 @@ "bus2Id": "Grid.ElmNet\\Bus_0011.ElmTerm", "typeId": "TypLne 0010 to 0011.TypLne" }, - { - "id": "Grid.ElmNet\\Line_0012_0013.ElmLne", - "GPScoords": [ - [] - ], - "dline": 1.0, - "bus1Id": "Grid.ElmNet\\Bus_0012.ElmTerm", - "bus2Id": "Grid.ElmNet\\Bus_0013.ElmTerm", - "typeId": "TypLne 0012 to 0013.TypLne" - }, { "id": "Grid.ElmNet\\Line_0013_0014.ElmLne", "GPScoords": [ @@ -517,14 +507,14 @@ "typeId": "TypLne 0013 to 0014.TypLne" }, { - "id": "Grid.ElmNet\\Line_0002_0005.ElmLne", + "id": "Grid.ElmNet\\Line_0002_0003.ElmLne", "GPScoords": [ [] ], "dline": 1.0, "bus1Id": "Grid.ElmNet\\Bus_0002.ElmTerm", - "bus2Id": "Grid.ElmNet\\Bus_0005.ElmTerm", - "typeId": "TypLne 0002 to 0005.TypLne" + "bus2Id": "Grid.ElmNet\\Bus_0003.ElmTerm", + "typeId": "TypLne 0002 to 0003.TypLne" }, { "id": "Grid.ElmNet\\Line_0006_0013.ElmLne", @@ -608,7 +598,7 @@ "typeId": "TypLne 0001 to 0002.TypLne" }, { - "id": "Grid.ElmNet\\Line_0001_0005.ElmLne", + "id": "Grid.ElmNet\\Line_0001_0002/2.ElmLne", "GPScoords": [ [ 1.0, @@ -625,11 +615,11 @@ ], "dline": 1.0, "bus1Id": "Grid.ElmNet\\Bus_0001.ElmTerm", - "bus2Id": "Grid.ElmNet\\Bus_0005.ElmTerm", - "typeId": "TypLne 0001 to 0005.TypLne" + "bus2Id": "Grid.ElmNet\\Bus_0002.ElmTerm", + "typeId": "TypLne 0001 to 0002.TypLne" }, { - "id": "Grid.ElmNet\\Line_0001_0002/2.ElmLne", + "id": "Grid.ElmNet\\Line_0002_0004.ElmLne", "GPScoords": [ [ 1.0, @@ -645,12 +635,12 @@ ] ], "dline": 1.0, - "bus1Id": "Grid.ElmNet\\Bus_0001.ElmTerm", - "bus2Id": "Grid.ElmNet\\Bus_0002.ElmTerm", - "typeId": "TypLne 0001 to 0002.TypLne" + "bus1Id": "Grid.ElmNet\\Bus_0002.ElmTerm", + "bus2Id": "Grid.ElmNet\\Bus_0004.ElmTerm", + "typeId": "TypLne 0002 to 0004.TypLne" }, { - "id": "Grid.ElmNet\\Line_0002_0004.ElmLne", + "id": "Grid.ElmNet\\Line_0003_0004.ElmLne", "GPScoords": [ [ 1.0, @@ -666,12 +656,12 @@ ] ], "dline": 1.0, - "bus1Id": "Grid.ElmNet\\Bus_0002.ElmTerm", + "bus1Id": "Grid.ElmNet\\Bus_0003.ElmTerm", "bus2Id": "Grid.ElmNet\\Bus_0004.ElmTerm", - "typeId": "TypLne 0002 to 0004.TypLne" + "typeId": "TypLne 0003 to 0004.TypLne" }, { - "id": "Grid.ElmNet\\Line_0003_0004.ElmLne", + "id": "Grid.ElmNet\\Line_0001_0005.ElmLne", "GPScoords": [ [ 1.0, @@ -687,20 +677,30 @@ ] ], "dline": 1.0, - "bus1Id": "Grid.ElmNet\\Bus_0003.ElmTerm", - "bus2Id": "Grid.ElmNet\\Bus_0004.ElmTerm", - "typeId": "TypLne 0003 to 0004.TypLne" + "bus1Id": "Grid.ElmNet\\Bus_0001.ElmTerm", + "bus2Id": "Grid.ElmNet\\Bus_0005.ElmTerm", + "typeId": "TypLne 0001 to 0005.TypLne" + }, + { + "id": "Grid.ElmNet\\Line_0012_0013.ElmLne", + "GPScoords": [ + [] + ], + "dline": 0.30000001192092896, + "bus1Id": "Grid.ElmNet\\Bus_0012.ElmTerm", + "bus2Id": "Grid.ElmNet\\Bus_0013.ElmTerm", + "typeId": "TypLne 0012 to 0013.TypLne" } ], "lineTypes": [ { - "id": "TypLne 0002 to 0003.TypLne", - "bline": 251.37741088867188, + "id": "TypLne 0002 to 0005.TypLne", + "bline": 195.13314819335938, "gline": 0.0, - "rline": 8.18753719329834, + "rline": 9.922967910766602, "sline": 1.0, "uline": 132.0, - "xline": 34.49428176879883 + "xline": 30.296852111816406 }, { "id": "TypLne 0010 to 0011.TypLne", @@ -711,15 +711,6 @@ "uline": 33.0, "xline": 2.0916426181793213 }, - { - "id": "TypLne 0012 to 0013.TypLne", - "bline": 0.0, - "gline": 0.0, - "rline": 2.4058187007904053, - "sline": 1.0, - "uline": 33.0, - "xline": 2.1766932010650635 - }, { "id": "TypLne 0013 to 0014.TypLne", "bline": 0.0, @@ -730,13 +721,13 @@ "xline": 3.78993821144104 }, { - "id": "TypLne 0002 to 0005.TypLne", - "bline": 195.13314819335938, + "id": "TypLne 0002 to 0003.TypLne", + "bline": 251.37741088867188, "gline": 0.0, - "rline": 9.922967910766602, + "rline": 8.18753719329834, "sline": 1.0, "uline": 132.0, - "xline": 30.296852111816406 + "xline": 34.49428176879883 }, { "id": "TypLne 0006 to 0013.TypLne", @@ -801,15 +792,6 @@ "uline": 132.0, "xline": 20.61956214904785 }, - { - "id": "TypLne 0001 to 0005.TypLne", - "bline": 282.369140625, - "gline": 0.0, - "rline": 9.41418743133545, - "sline": 1.0, - "uline": 132.0, - "xline": 38.86250305175781 - }, { "id": "TypLne 0002 to 0004.TypLne", "bline": 214.64646911621094, @@ -827,6 +809,24 @@ "sline": 1.0, "uline": 132.0, "xline": 29.80026626586914 + }, + { + "id": "TypLne 0001 to 0005.TypLne", + "bline": 282.369140625, + "gline": 0.0, + "rline": 9.41418743133545, + "sline": 1.0, + "uline": 132.0, + "xline": 38.86250305175781 + }, + { + "id": "TypLne 0012 to 0013.TypLne", + "bline": 0.0, + "gline": 0.0, + "rline": 2.4058187007904053, + "sline": 1.0, + "uline": 33.0, + "xline": 2.1766932010650635 } ], "trafos2w": [ From cb2e136703c7700f87a46512949718f479aa2f09 Mon Sep 17 00:00:00 2001 From: t-ober <63147366+t-ober@users.noreply.github.com> Date: Wed, 24 Nov 2021 10:36:46 +0100 Subject: [PATCH 24/24] remove unused import --- .../edu/ie3/powerFactory2psdm/converter/LineConverter.scala | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/scala/edu/ie3/powerFactory2psdm/converter/LineConverter.scala b/src/main/scala/edu/ie3/powerFactory2psdm/converter/LineConverter.scala index e6c6eec3..a6bdb667 100644 --- a/src/main/scala/edu/ie3/powerFactory2psdm/converter/LineConverter.scala +++ b/src/main/scala/edu/ie3/powerFactory2psdm/converter/LineConverter.scala @@ -7,20 +7,17 @@ package edu.ie3.powerFactory2psdm.converter import edu.ie3.datamodel.models.StandardUnits -import tech.units.indriya.unit.Units.METRE import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.connector.LineInput import edu.ie3.datamodel.models.input.connector.`type`.LineTypeInput import edu.ie3.datamodel.models.input.system.characteristic.OlmCharacteristicInput import edu.ie3.datamodel.utils.GridAndGeoUtils import edu.ie3.powerFactory2psdm.converter.NodeConverter.getNode -import edu.ie3.powerFactory2psdm.converter.types.LineTypeConverter import edu.ie3.powerFactory2psdm.converter.types.LineTypeConverter.getLineType import edu.ie3.powerFactory2psdm.exception.pf.ConversionException import edu.ie3.powerFactory2psdm.model.entity.Line import edu.ie3.powerFactory2psdm.model.setting.ConversionPrefixes.ConversionPrefix import edu.ie3.powerFactory2psdm.util.QuantityUtils.RichQuantityDouble -import tech.units.indriya.quantity.Quantities import java.util.UUID import scala.util.{Failure, Success}