diff --git a/src/main/scala/edu/ie3/simbench/convert/GridConverter.scala b/src/main/scala/edu/ie3/simbench/convert/GridConverter.scala index e1c25b5c..c8be6f83 100644 --- a/src/main/scala/edu/ie3/simbench/convert/GridConverter.scala +++ b/src/main/scala/edu/ie3/simbench/convert/GridConverter.scala @@ -61,7 +61,7 @@ case object GridConverter extends LazyLogging { removeSwitches: Boolean ): ( JointGridContainer, - Vector[IndividualTimeSeries[_ <: PValue]], + Set[IndividualTimeSeries[_ <: PValue]], Seq[MappingEntry], Vector[NodeResult] ) = { @@ -610,7 +610,7 @@ case object GridConverter extends LazyLogging { nodeConversion: Map[Node, NodeInput] ): ( SystemParticipants, - Vector[IndividualTimeSeries[_ <: PValue]], + Set[IndividualTimeSeries[_ <: PValue]], Seq[MappingEntry] ) = { /* Convert all participant groups */ @@ -640,8 +640,8 @@ case object GridConverter extends LazyLogging { timeSeries.getUuid ) }.toSeq - val timeSeries: Vector[IndividualTimeSeries[_ >: SValue <: PValue]] = - participantsToTimeSeries.map(_._2).toVector + val timeSeries: Set[IndividualTimeSeries[_ <: PValue]] = + participantsToTimeSeries.map(_._2).toSet ( new SystemParticipants( diff --git a/src/main/scala/edu/ie3/simbench/convert/LoadConverter.scala b/src/main/scala/edu/ie3/simbench/convert/LoadConverter.scala index 4cf794b5..c4931674 100644 --- a/src/main/scala/edu/ie3/simbench/convert/LoadConverter.scala +++ b/src/main/scala/edu/ie3/simbench/convert/LoadConverter.scala @@ -1,40 +1,52 @@ package edu.ie3.simbench.convert -import java.util.{Locale, UUID} +import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed -import edu.ie3.datamodel.models.input.{EmInput, NodeInput, OperatorInput} +import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.profile.LoadProfile.DefaultLoadProfiles import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries import edu.ie3.datamodel.models.value.SValue import edu.ie3.simbench.convert.profiles.PowerProfileConverter import edu.ie3.simbench.model.datamodel.profiles.{LoadProfile, LoadProfileType} import edu.ie3.simbench.model.datamodel.{Load, Node} -import edu.ie3.util.quantities.PowerSystemUnits.{ - KILOWATTHOUR, - MEGAVAR, - MEGAVOLTAMPERE, - MEGAWATT -} +import edu.ie3.util.quantities.PowerSystemUnits.{KILOWATTHOUR, MEGAVOLTAMPERE} import tech.units.indriya.quantity.Quantities +import java.util.{Locale, UUID} import scala.collection.parallel.CollectionConverters._ -case object LoadConverter extends ShuntConverter { +case object LoadConverter extends ShuntConverter with LazyLogging { def convert( loads: Vector[Load], nodes: Map[Node, NodeInput], profiles: Map[LoadProfileType, LoadProfile] - ): Map[LoadInput, IndividualTimeSeries[SValue]] = + ): Map[LoadInput, IndividualTimeSeries[SValue]] = { + + val modelScalings = loads + .map { input => + input.profile -> (input.pLoad, input.qLoad) + } + .groupBy(_._1) + .map { entry => entry._1 -> entry._2.map(_._2).toSet } + + val convertedTimeSeries = PowerProfileConverter.convertS( + modelScalings, + profiles + ) + + logger.debug("Resulting load time series: {]", convertedTimeSeries.size) + loads.par .map { load => val node = NodeConverter.getNode(load.node, nodes) - val profile = PowerProfileConverter.getProfile(load.profile, profiles) - convert(load, node, profile) + val series = convertedTimeSeries((load.profile, load.pLoad, load.qLoad)) + convert(load, node) -> series } .seq .toMap + } /** Converts a single SimBench [[Load]] to ie3's [[LoadInput]]. Currently not * sufficiently covered: @@ -45,8 +57,6 @@ case object LoadConverter extends ShuntConverter { * Input model * @param node * Node, the load is connected to - * @param profile - * SimBench load profile * @param uuid * UUID to use for the model generation (default: Random UUID) * @return @@ -55,9 +65,8 @@ case object LoadConverter extends ShuntConverter { def convert( input: Load, node: NodeInput, - profile: LoadProfile, uuid: UUID = UUID.randomUUID() - ): (LoadInput, IndividualTimeSeries[SValue]) = { + ): LoadInput = { val id = input.id val cosphi = cosPhi(input.pLoad, input.qLoad) val varCharacteristicString = @@ -65,10 +74,6 @@ case object LoadConverter extends ShuntConverter { val eCons = Quantities.getQuantity(0d, KILOWATTHOUR) val sRated = Quantities.getQuantity(input.sR, MEGAVOLTAMPERE) - val p = Quantities.getQuantity(input.pLoad, MEGAWATT) - val q = Quantities.getQuantity(input.qLoad, MEGAVAR) - val timeSeries = PowerProfileConverter.convert(profile, p, q) - new LoadInput( uuid, id, @@ -82,7 +87,6 @@ case object LoadConverter extends ShuntConverter { eCons, sRated, cosphi - ) -> - timeSeries + ) } } diff --git a/src/main/scala/edu/ie3/simbench/convert/PowerPlantConverter.scala b/src/main/scala/edu/ie3/simbench/convert/PowerPlantConverter.scala index 5933cbdc..b0d350ff 100644 --- a/src/main/scala/edu/ie3/simbench/convert/PowerPlantConverter.scala +++ b/src/main/scala/edu/ie3/simbench/convert/PowerPlantConverter.scala @@ -1,7 +1,8 @@ package edu.ie3.simbench.convert -import java.util.{Locale, UUID} +import com.typesafe.scalalogging.LazyLogging +import java.util.{Locale, UUID} import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.system.FixedFeedInInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed @@ -23,7 +24,7 @@ import tech.units.indriya.quantity.Quantities import scala.collection.parallel.CollectionConverters._ -case object PowerPlantConverter extends ShuntConverter { +case object PowerPlantConverter extends ShuntConverter with LazyLogging { /** Convert a full set of power plants * @@ -41,16 +42,34 @@ case object PowerPlantConverter extends ShuntConverter { powerPlants: Vector[PowerPlant], nodes: Map[Node, NodeInput], profiles: Map[PowerPlantProfileType, PowerPlantProfile] - ): Map[FixedFeedInInput, IndividualTimeSeries[PValue]] = + ): Map[FixedFeedInInput, IndividualTimeSeries[PValue]] = { + + val modelScalings = powerPlants + .map { input => + input.profile -> input.p + } + .groupBy(_._1) + .map { entry => entry._1 -> entry._2.map(_._2).toSet } + + val convertedTimeSeries = PowerProfileConverter.convertP( + modelScalings, + profiles + ) + + logger.debug( + "Resulting power plant time series: {]", + convertedTimeSeries.size + ) + powerPlants.par .map { powerPlant => val node = NodeConverter.getNode(powerPlant.node, nodes) - val profile = - PowerProfileConverter.getProfile(powerPlant.profile, profiles) - convert(powerPlant, node, profile) + val series = convertedTimeSeries((powerPlant.profile, powerPlant.p)) + convert(powerPlant, node) -> series } .seq .toMap + } /** Converts a single power plant model to a fixed feed in model, as the power * system data model does not reflect power plants, yet. Voltage regulation @@ -60,8 +79,6 @@ case object PowerPlantConverter extends ShuntConverter { * Input model * @param node * Node, the power plant is connected to - * @param profile - * SimBench power plant profile * @param uuid * Option to a specific uuid * @return @@ -70,9 +87,8 @@ case object PowerPlantConverter extends ShuntConverter { def convert( input: PowerPlant, node: NodeInput, - profile: PowerPlantProfile, uuid: Option[UUID] = None - ): (FixedFeedInInput, IndividualTimeSeries[PValue]) = { + ): FixedFeedInInput = { val p = Quantities.getQuantity(input.p, MEGAWATT) val q = input.q match { case Some(value) => Quantities.getQuantity(value, MEGAVAR) @@ -83,9 +99,6 @@ case object PowerPlantConverter extends ShuntConverter { "cosPhiFixed:{(0.0,%#.2f)}".formatLocal(Locale.ENGLISH, cosphi) val sRated = Quantities.getQuantity(input.sR, MEGAVOLTAMPERE) - /* Flip the sign, as infeed is negative in PowerSystemDataModel */ - val timeSeries = PowerProfileConverter.convert(profile, p.multiply(-1)) - new FixedFeedInInput( uuid.getOrElse(UUID.randomUUID()), input.id, @@ -96,6 +109,6 @@ case object PowerPlantConverter extends ShuntConverter { null, sRated, cosphi - ) -> timeSeries + ) } } diff --git a/src/main/scala/edu/ie3/simbench/convert/ResConverter.scala b/src/main/scala/edu/ie3/simbench/convert/ResConverter.scala index 4b254396..aa687c83 100644 --- a/src/main/scala/edu/ie3/simbench/convert/ResConverter.scala +++ b/src/main/scala/edu/ie3/simbench/convert/ResConverter.scala @@ -1,7 +1,6 @@ package edu.ie3.simbench.convert -import java.util.{Locale, UUID} - +import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.system.FixedFeedInInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed @@ -18,9 +17,10 @@ import edu.ie3.util.quantities.PowerSystemUnits.{ } import tech.units.indriya.quantity.Quantities +import java.util.{Locale, UUID} import scala.collection.parallel.CollectionConverters._ -case object ResConverter extends ShuntConverter { +case object ResConverter extends ShuntConverter with LazyLogging { /** Convert a full set of renewable energy source system * @@ -38,16 +38,31 @@ case object ResConverter extends ShuntConverter { res: Vector[RES], nodes: Map[Node, NodeInput], profiles: Map[ResProfileType, ResProfile] - ): Map[FixedFeedInInput, IndividualTimeSeries[PValue]] = + ): Map[FixedFeedInInput, IndividualTimeSeries[PValue]] = { + + val modelScalings = res + .map { input => + input.profile -> input.p + } + .groupBy(_._1) + .map { entry => entry._1 -> entry._2.map(_._2).toSet } + + val convertedTimeSeries = PowerProfileConverter.convertP( + modelScalings, + profiles + ) + + logger.debug("Resulting RES time series: {]", convertedTimeSeries.size) + res.par .map { plant => val node = NodeConverter.getNode(plant.node, nodes) - val profile = - PowerProfileConverter.getProfile(plant.profile, profiles) - convert(plant, node, profile) + val series = convertedTimeSeries((plant.profile, plant.p)) + convert(plant, node) -> series } .seq .toMap + } /** Converts a single renewable energy source system to a fixed feed in model * due to lacking information to sophistically guess typical types of assets. @@ -57,8 +72,6 @@ case object ResConverter extends ShuntConverter { * Input model * @param node * Node, the renewable energy source system is connected to - * @param profile - * SimBench renewable energy source system profile * @param uuid * Option to a specific uuid * @return @@ -67,9 +80,8 @@ case object ResConverter extends ShuntConverter { def convert( input: RES, node: NodeInput, - profile: ResProfile, uuid: Option[UUID] = None - ): (FixedFeedInInput, IndividualTimeSeries[PValue]) = { + ): FixedFeedInInput = { val p = Quantities.getQuantity(input.p, MEGAWATT) val q = Quantities.getQuantity(input.q, MEGAVAR) val cosphi = cosPhi(p.getValue.doubleValue(), q.getValue.doubleValue()) @@ -77,9 +89,6 @@ case object ResConverter extends ShuntConverter { "cosPhiFixed:{(0.0,%#.2f)}".formatLocal(Locale.ENGLISH, cosphi) val sRated = Quantities.getQuantity(input.sR, MEGAVOLTAMPERE) - /* Flip the sign, as infeed is negative in PowerSystemDataModel */ - val timeSeries = PowerProfileConverter.convert(profile, p.multiply(-1)) - new FixedFeedInInput( uuid.getOrElse(UUID.randomUUID()), input.id + "_" + input.resType.toString, @@ -90,6 +99,6 @@ case object ResConverter extends ShuntConverter { null, sRated, cosphi - ) -> timeSeries + ) } } diff --git a/src/main/scala/edu/ie3/simbench/convert/profiles/PowerProfileConverter.scala b/src/main/scala/edu/ie3/simbench/convert/profiles/PowerProfileConverter.scala index 1bbfe9cb..63787d68 100644 --- a/src/main/scala/edu/ie3/simbench/convert/profiles/PowerProfileConverter.scala +++ b/src/main/scala/edu/ie3/simbench/convert/profiles/PowerProfileConverter.scala @@ -1,7 +1,5 @@ package edu.ie3.simbench.convert.profiles -import java.util.UUID - import edu.ie3.datamodel.models.timeseries.individual.{ IndividualTimeSeries, TimeBasedValue @@ -9,13 +7,49 @@ import edu.ie3.datamodel.models.timeseries.individual.{ import edu.ie3.datamodel.models.value.{PValue, SValue} import edu.ie3.simbench.exception.ConversionException import edu.ie3.simbench.model.datamodel.profiles.{ProfileModel, ProfileType} -import javax.measure.quantity.Power +import edu.ie3.util.quantities.PowerSystemUnits.{MEGAVAR, MEGAWATT} import tech.units.indriya.ComparableQuantity +import tech.units.indriya.quantity.Quantities +import java.util.UUID +import javax.measure.quantity.Power +import scala.collection.parallel.CollectionConverters.ImmutableIterableIsParallelizable import scala.jdk.CollectionConverters._ case object PowerProfileConverter { + /** Converts the given profiles with the given model scalings into ie3's data + * model time series. + * + * @param modelScalings + * models with active and reactive power scalings + * @param profiles + * to convert + * @return + * a map of profile type and scaling factors to [[IndividualTimeSeries]] + * with active and reactive power for each time step + */ + def convertS[ + T <: ProfileType, + P <: ProfileModel[T, (BigDecimal, BigDecimal)] + ]( + modelScalings: Map[T, Set[(BigDecimal, BigDecimal)]], + profiles: Map[T, P] + ): Map[(T, BigDecimal, BigDecimal), IndividualTimeSeries[SValue]] = + profiles.keySet.par + .flatMap { key => + val profile: P = profiles(key) + + modelScalings(key).map { case (pLoad, qLoad) => + val p = Quantities.getQuantity(pLoad, MEGAWATT) + val q = Quantities.getQuantity(qLoad, MEGAVAR) + + (key, pLoad, qLoad) -> PowerProfileConverter.convert(profile, p, q) + } + } + .seq + .toMap + /** Converts a given profile with a tuple of BigDecimal as data to a ie3's * data model time series denoting a tuple of active and reactive power. The * SimBench model gives only scaling factors for active and reactive power, @@ -46,6 +80,38 @@ case object PowerProfileConverter { new IndividualTimeSeries[SValue](UUID.randomUUID(), values.asJava) } + /** Converts the given profiles with the given model scalings into ie3's data + * model time series. + * + * @param modelScalings + * models with active power scaling + * @param profiles + * to convert + * @return + * a map of profile type and scaling factor to [[IndividualTimeSeries]] + * with active power for each time step + */ + def convertP[T <: ProfileType, P <: ProfileModel[T, BigDecimal]]( + modelScalings: Map[T, Set[BigDecimal]], + profiles: Map[T, P] + ): Map[(T, BigDecimal), IndividualTimeSeries[PValue]] = + profiles.keySet.par + .flatMap { key => + val profile: P = profiles(key) + + modelScalings(key).map { pLoad => + val p = Quantities.getQuantity(pLoad, MEGAWATT) + + /* Flip the sign, as infeed is negative in PowerSystemDataModel */ + val timeSeries = + PowerProfileConverter.convert(profile, p.multiply(-1)) + + (key, pLoad) -> timeSeries + } + } + .seq + .toMap + /** Converts a given profile with s single BigDecimal as data to a ie3's data * model time series denoting active power. The SimBench model gives only * scaling factors for active power, which will scale the maximum active @@ -56,8 +122,7 @@ case object PowerProfileConverter { * @param pRated * Reference active power to meet the peak point of the profile * @return - * A [[IndividualTimeSeries]] with active and reactive power for each time - * step + * A [[IndividualTimeSeries]] with active power for each time step */ def convert( profileModel: ProfileModel[_ <: ProfileType, BigDecimal], diff --git a/src/main/scala/edu/ie3/simbench/main/RunSimbench.scala b/src/main/scala/edu/ie3/simbench/main/RunSimbench.scala index a2e0c803..81772c83 100644 --- a/src/main/scala/edu/ie3/simbench/main/RunSimbench.scala +++ b/src/main/scala/edu/ie3/simbench/main/RunSimbench.scala @@ -47,6 +47,14 @@ object RunSimbench extends SimbenchHelper { val uuidMap = extractor.extractUUIDMap() simbenchConfig.io.simbenchCodes.foreach { simbenchCode => + // todo: replace these two if statements with a proper handling of switches + if (!simbenchConfig.conversion.removeSwitches) { + logger.warn(s"Currently, removing switches might be necessary.") + } + if (simbenchCode.contains("-sw")) { + logger.warn(s"Using a simbench grid with '-sw' might not work.") + } + logger.info(s"$simbenchCode - Downloading data set from SimBench website") val downloader = Downloader( diff --git a/src/test/scala/edu/ie3/simbench/convert/GridConverterSpec.scala b/src/test/scala/edu/ie3/simbench/convert/GridConverterSpec.scala index 5bf1cc3f..c375c6b1 100644 --- a/src/test/scala/edu/ie3/simbench/convert/GridConverterSpec.scala +++ b/src/test/scala/edu/ie3/simbench/convert/GridConverterSpec.scala @@ -176,7 +176,7 @@ class GridConverterSpec extends UnitSpec with SwitchTestingData { .empty[Class[_ <: UniqueEntity], Int] /* Evaluate the correctness of the time series by counting the occurrence of models */ - timeSeries.size shouldBe 17 + timeSeries.size shouldBe 16 /* Evaluate the existence of time series mappings for all participants */ timeSeriesMapping.size shouldBe 17 diff --git a/src/test/scala/edu/ie3/simbench/convert/LoadConverterSpec.scala b/src/test/scala/edu/ie3/simbench/convert/LoadConverterSpec.scala index a2ee6f44..68106e17 100644 --- a/src/test/scala/edu/ie3/simbench/convert/LoadConverterSpec.scala +++ b/src/test/scala/edu/ie3/simbench/convert/LoadConverterSpec.scala @@ -19,7 +19,7 @@ class LoadConverterSpec extends UnitSpec with ConverterTestData { "The load converter" should { "convert a single model correctly" in { /* Time series conversion is tested in a single test */ - val (actual, _) = LoadConverter.convert(input, node, inputProfile) + val actual = LoadConverter.convert(input, node) actual.getId shouldBe actual.getId actual.getNode shouldBe expected.getNode diff --git a/src/test/scala/edu/ie3/simbench/convert/PowerPlantConverterSpec.scala b/src/test/scala/edu/ie3/simbench/convert/PowerPlantConverterSpec.scala index 95eedeb9..04f3c2e2 100644 --- a/src/test/scala/edu/ie3/simbench/convert/PowerPlantConverterSpec.scala +++ b/src/test/scala/edu/ie3/simbench/convert/PowerPlantConverterSpec.scala @@ -1,6 +1,7 @@ package edu.ie3.simbench.convert import edu.ie3.datamodel.models.StandardUnits +import edu.ie3.simbench.model.datamodel.profiles.PowerPlantProfileType.PowerPlantProfile1 import edu.ie3.simbench.model.datamodel.profiles.{ PowerPlantProfile, PowerPlantProfileType @@ -18,7 +19,8 @@ class PowerPlantConverterSpec "The power plant converter" when { "converting a power plant without reactive power information" should { val (input, expected) = getPowerPlantPair("EHV Gen 1") - val node = getNodePair("EHV Bus 177")._2 + val (node, nodeInput) = getNodePair("EHV Bus 177") + val pProfile: PowerPlantProfile = PowerPlantProfile( "test profile", PowerPlantProfileType.PowerPlantProfile1, @@ -45,16 +47,24 @@ class PowerPlantConverterSpec ) ) ) - val (actual, actualTimeSeries) = - PowerPlantConverter.convert(input, node, pProfile) + + val profiles: Map[PowerPlantProfileType, PowerPlantProfile] = + Map(PowerPlantProfile1 -> pProfile) + val actual = PowerPlantConverter.convert( + Vector(input), + Map(node -> nodeInput), + profiles + ) + val actualPowerPlant = actual.keySet.toSeq(0) + val actualTimeSeries = actual(actualPowerPlant) "bring up the correct input model" in { - actual.getId shouldBe expected.getId - actual.getNode shouldBe expected.getNode - actual.getOperator shouldBe expected.getOperator - actual.getqCharacteristics shouldBe expected.getqCharacteristics - actual.getsRated shouldBe expected.getsRated - actual.getCosPhiRated shouldBe expected.getCosPhiRated + actualPowerPlant.getId shouldBe expected.getId + actualPowerPlant.getNode shouldBe expected.getNode + actualPowerPlant.getOperator shouldBe expected.getOperator + actualPowerPlant.getqCharacteristics shouldBe expected.getqCharacteristics + actualPowerPlant.getsRated shouldBe expected.getsRated + actualPowerPlant.getCosPhiRated shouldBe expected.getCosPhiRated } "lead to the correct time series" in { @@ -97,7 +107,8 @@ class PowerPlantConverterSpec "converting a power plant with reactive power information" should { val (input, expected) = getPowerPlantPair("EHV Gen 1_withQ") - val node = getNodePair("EHV Bus 177")._2 + val (node, nodeInput) = getNodePair("EHV Bus 177") + val pProfile: PowerPlantProfile = PowerPlantProfile( "test profile", PowerPlantProfileType.PowerPlantProfile1, @@ -124,16 +135,24 @@ class PowerPlantConverterSpec ) ) ) - val (actual, actualTimeSeries) = - PowerPlantConverter.convert(input, node, pProfile) + + val profiles: Map[PowerPlantProfileType, PowerPlantProfile] = + Map(PowerPlantProfile1 -> pProfile) + val actual = PowerPlantConverter.convert( + Vector(input), + Map(node -> nodeInput), + profiles + ) + val actualPowerPlant = actual.keySet.toSeq(0) + val actualTimeSeries = actual(actualPowerPlant) "bring up the correct input model" in { - actual.getId shouldBe expected.getId - actual.getNode shouldBe expected.getNode - actual.getOperator shouldBe expected.getOperator - actual.getqCharacteristics shouldBe expected.getqCharacteristics - actual.getsRated shouldBe expected.getsRated - actual.getCosPhiRated shouldBe expected.getCosPhiRated + actualPowerPlant.getId shouldBe expected.getId + actualPowerPlant.getNode shouldBe expected.getNode + actualPowerPlant.getOperator shouldBe expected.getOperator + actualPowerPlant.getqCharacteristics shouldBe expected.getqCharacteristics + actualPowerPlant.getsRated shouldBe expected.getsRated + actualPowerPlant.getCosPhiRated shouldBe expected.getCosPhiRated } "lead to the correct time series" in { diff --git a/src/test/scala/edu/ie3/simbench/convert/ResConverterSpec.scala b/src/test/scala/edu/ie3/simbench/convert/ResConverterSpec.scala index a6b69349..27b7c909 100644 --- a/src/test/scala/edu/ie3/simbench/convert/ResConverterSpec.scala +++ b/src/test/scala/edu/ie3/simbench/convert/ResConverterSpec.scala @@ -1,6 +1,8 @@ package edu.ie3.simbench.convert import edu.ie3.datamodel.models.StandardUnits +import edu.ie3.simbench.model.datamodel.enums.ResType +import edu.ie3.simbench.model.datamodel.enums.ResType.LvRural1 import java.util.Objects import edu.ie3.simbench.model.datamodel.profiles.{ResProfile, ResProfileType} @@ -17,8 +19,9 @@ class ResConverterSpec implicit val quantityMatchingTolerance: Double = 1e-4 "The RES converter" should { - val (_, node) = getNodePair("MV1.101 Bus 4") + val (node, nodeInput) = getNodePair("MV1.101 Bus 4") val (input, expected) = getResPair("MV1.101 SGen 2") + val pProfile: ResProfile = ResProfile( "test profile", ResProfileType.LvRural1, @@ -45,17 +48,23 @@ class ResConverterSpec ) ) ) - val (actual, actualTimeSeries) = ResConverter.convert(input, node, pProfile) + + val profiles: Map[ResProfileType, ResProfile] = + Map(ResProfileType.LvRural1 -> pProfile) + val actual = + ResConverter.convert(Vector(input), Map(node -> nodeInput), profiles) + val actualRes = actual.keySet.toSeq(0) + val actualTimeSeries = actual(actualRes) "bring up the correct input model" in { - Objects.nonNull(actual.getUuid) shouldBe true - actual.getId shouldBe expected.getId - actual.getOperator shouldBe expected.getOperator - actual.getOperationTime shouldBe expected.getOperationTime - actual.getNode shouldBe expected.getNode - actual.getqCharacteristics shouldBe expected.getqCharacteristics - actual.getsRated shouldBe expected.getsRated - actual.getCosPhiRated shouldBe expected.getCosPhiRated + Objects.nonNull(actualRes.getUuid) shouldBe true + actualRes.getId shouldBe expected.getId + actualRes.getOperator shouldBe expected.getOperator + actualRes.getOperationTime shouldBe expected.getOperationTime + actualRes.getNode shouldBe expected.getNode + actualRes.getqCharacteristics shouldBe expected.getqCharacteristics + actualRes.getsRated shouldBe expected.getsRated + actualRes.getCosPhiRated shouldBe expected.getCosPhiRated } "lead to the correct time series" in { diff --git a/src/test/scala/edu/ie3/simbench/convert/profiles/PowerProfileConverterSpec.scala b/src/test/scala/edu/ie3/simbench/convert/profiles/PowerProfileConverterSpec.scala index 016c7424..4fd64844 100644 --- a/src/test/scala/edu/ie3/simbench/convert/profiles/PowerProfileConverterSpec.scala +++ b/src/test/scala/edu/ie3/simbench/convert/profiles/PowerProfileConverterSpec.scala @@ -141,62 +141,62 @@ class PowerProfileConverterSpec extends UnitSpec { } case None => throw ConversionException( - s"Cannot find a time series entry for ${time}" + s"Cannot find a time series entry for $time" ) } ) < testingTolerance } } - } - "correctly convert an active power time series" in { - val pRated = Quantities.getQuantity(100d, KILOWATT) + "correctly convert an active power time series" in { + val pRated = Quantities.getQuantity(100d, KILOWATT) - val expected = Map( - TestTimeUtils.international - .toZonedDateTime("1990-01-01 00:00:00") -> new PValue( - Quantities.getQuantity(75d, KILOWATT) - ), - TestTimeUtils.international - .toZonedDateTime("1990-01-01 00:15:00") -> new PValue( - Quantities.getQuantity(55d, KILOWATT) - ), - TestTimeUtils.international - .toZonedDateTime("1990-01-01 00:30:00") -> new PValue( - Quantities.getQuantity(35d, KILOWATT) - ), - TestTimeUtils.international - .toZonedDateTime("1990-01-01 00:45:00") -> new PValue( - Quantities.getQuantity(15d, KILOWATT) + val expected = Map( + TestTimeUtils.international + .toZonedDateTime("1990-01-01 00:00:00") -> new PValue( + Quantities.getQuantity(75d, KILOWATT) + ), + TestTimeUtils.international + .toZonedDateTime("1990-01-01 00:15:00") -> new PValue( + Quantities.getQuantity(55d, KILOWATT) + ), + TestTimeUtils.international + .toZonedDateTime("1990-01-01 00:30:00") -> new PValue( + Quantities.getQuantity(35d, KILOWATT) + ), + TestTimeUtils.international + .toZonedDateTime("1990-01-01 00:45:00") -> new PValue( + Quantities.getQuantity(15d, KILOWATT) + ) ) - ) - val actual = PowerProfileConverter.convert(pProfile, pRated) + val actual = PowerProfileConverter.convert(pProfile, pRated) - expected.foreach { case (time, pValue) => - abs( - actual - .getValue(time) - .toScala match { - case Some(value) => - (value.getP.toScala, pValue.getP.toScala) match { - case (Some(lhs), Some(rhs)) => - lhs - .subtract(rhs) - .to(KILOWATT) - .getValue - .doubleValue() - case _ => - throw ConversionException( - s"Unable to calculate difference between expected und actual time series, as one of both entries is not available for time $time" - ) - } - case None => - throw ConversionException( - s"Cannot find a time series entry for $time" - ) - } - ) < testingTolerance + expected.foreach { case (time, pValue) => + abs( + actual + .getValue(time) + .toScala match { + case Some(value) => + (value.getP.toScala, pValue.getP.toScala) match { + case (Some(lhs), Some(rhs)) => + lhs + .subtract(rhs) + .to(KILOWATT) + .getValue + .doubleValue() + case _ => + throw ConversionException( + s"Unable to calculate difference between expected und actual time series, as one of both entries is not available for time $time" + ) + } + case None => + throw ConversionException( + s"Cannot find a time series entry for $time" + ) + } + ) < testingTolerance + } } } } diff --git a/src/test/scala/edu/ie3/simbench/io/DownloaderSpec.scala b/src/test/scala/edu/ie3/simbench/io/DownloaderSpec.scala index c3f2a8b9..69e64f0d 100644 --- a/src/test/scala/edu/ie3/simbench/io/DownloaderSpec.scala +++ b/src/test/scala/edu/ie3/simbench/io/DownloaderSpec.scala @@ -1,14 +1,13 @@ package edu.ie3.simbench.io -import java.io.File -import java.nio.file.Paths - import edu.ie3.simbench.exception.CodeValidationException import edu.ie3.simbench.exception.io.DownloaderException import edu.ie3.simbench.model.SimbenchCode import edu.ie3.test.common.UnitSpec import edu.ie3.util.io.FileIOUtils +import java.io.File +import java.nio.file.Paths import scala.language.postfixOps import scala.util.{Failure, Success, Try}